home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-07-23 | 88.8 KB | 3,086 lines | [TEXT/CWIE] |
- /*************************************************************************************
-
- File: ISpSampleUSB.cp
-
- Copyright © 1996, 1997, 1998 Apple Computer, Inc., All Rights Reserved
-
-
- You may incorporate this sample code into your applications without
- restriction, though the sample code has been provided "AS IS" and the
- responsibility for its operation is 100% yours. However, what you are
- not permitted to do is to redistribute the source as "DSC Sample Code"
- after having made changes. If you're going to re-distribute the source,
- we require that you make it clear in the source that the code was
- descended from Apple Sample Code, but that you've made changes.
-
- *************************************************************************************/
-
- #ifndef __INPUTSPROCKET__
- #include <InputSprocket.h>
- #endif
-
- #include "InputSprocketDriver.h"
- #include "ISpSampleUSB.h"
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
-
- #ifndef __QDOFFSCREEN__
- #include <QDOffscreen.h>
- #endif
-
- #ifndef __DESKBUS__
- #include <DeskBus.h>
- #endif
-
- #include <USB.h>
-
- #include "UniversalHIDModule.h"
-
- #include "ISpPlugInUI.h"
- #include "dprintf.h"
-
- #include "Common.h"
- #include "DialogUtils.h"
- #include "ListUtils.h"
- #include "ResourceUtils.h"
- #include "String_Utils.h"
-
- List * ISpUSBDevice::gUSBDevices;
-
- static ISpElementLabel USBElementKeyToLabel(short usbElementKey);
-
- extern "C" void MyUHIDInterruptProc (void *theData, UInt32 refcon);
-
- ISpUSBDevice::ISpUSBDevice(
- const UHIDModuleDispatchTablePtr hidmoduleDispatchTable,
- const USBDeviceRef usbDeviceRef,
- const FSSpec &inFileSpec)
- {
- // assign our arguments
- mHIDModuleDispatchTable = 0;
-
- // Save our ref (must happen before callback install)
- mUSBDeviceRef = usbDeviceRef;
-
- {
- mConnectionNotifyPB.usbDeviceNotification = kNotifyRemoveInterface;
- mConnectionNotifyPB.usbClass = kUSBHIDClass;
- mConnectionNotifyPB.usbSubClass = kUSBNoInterfaceSubClass;
- mConnectionNotifyPB.usbProtocol = kUSBNoInterfaceProtocol;
- mConnectionNotifyPB.usbVendor = -1;
- mConnectionNotifyPB.usbProduct = -1;
- mConnectionNotifyPB.callback = (USBDeviceNotificationCallbackProcPtr) &ISpUSBDevice::UIDNotifyProc;
- mConnectionNotifyPB.refcon = (UInt32) this;
-
- ::USBInstallDeviceNotification(&mConnectionNotifyPB);
- if (noErr == mConnectionNotifyPB.result)
- {
- mHIDModuleDispatchTable = hidmoduleDispatchTable;
- }
- }
-
- mFileSpec = inFileSpec;
-
- // clear the device
- mDevice = nil;
-
- // intialize ui variables
- mDialog = nil;
- mBaseDITLCount = nil;
- mResRef = nil;
- mVisable = false;
- mVirtualElementsValid = false; // Init has not been called yet
- mActive = false;
- mPatched = false;
-
- mReverseStick = false;
- mReverseRudder = false;
- mReverseThrottle = false;
- mReverseThrottle = false;
- mReverseRudder = false;
- mReverseDPad[0] = false;
- mReverseDPad[1] = false;
- mReverseDPad[2] = false;
- mReverseDPad[3] = false;
- }
-
- ISpUSBDevice::~ISpUSBDevice()
- {
- if (mPatched) { Unpatch(); }
- DisposeMapping();
-
- {
- mHIDModuleDispatchTable = 0; // lose the reference for sure
-
- ::USBRemoveDeviceNotification(mConnectionNotifyPB.token);
- }
- }
-
- void ISpUSBDevice::FinishConstruction(void)
- {
- OSStatus err;
-
- short ref;
- ref = FSpOpenResFile(&mFileSpec, fsRdPerm);
- BuildMapping();
- CloseResFile(ref);
-
- GetFeatures();
-
- for(UInt32 itr = 0; itr <= kDialogItem_NumPopups; itr++)
- mDialogItemToNeedMapping[itr] = kUnsetIndex;
-
- ClearVirtuals ();
-
- err = Patch();
- WARNING(err == noErr, "Patch failed in ISpUSBDevice::ISpUSBDevice");
-
- mActive = false;
- SetActive (true);
- }
-
- /* =============================================================================
- * Patch (private)
- *
- * Installs the appropriate patch for this mouse.
- * ========================================================================== */
- OSStatus ISpUSBDevice::Patch(void)
- {
- WARNING(mPatched == false, "ISpUSBDevice Unpatch called but were are not patched!");
-
- OSStatus err;
-
- if (0 != mHIDModuleDispatchTable)
- {
- err = (*mHIDModuleDispatchTable->pUHIDClaimDevice)(&mUHIDConnectionID, 0);
- WARNING(err == noErr, "USBDevice UHIDClaimDevice failed in Patch");
-
- if (err == noErr)
- {
- // Install our handler
- err = (*mHIDModuleDispatchTable->pUHIDInstallInterrupt)(mUHIDConnectionID, MyUHIDInterruptProc, (UInt32) this);
- WARNING(err == noErr, "USBDevice UHIDInstallInterrupt failed in Patch");
- }
- }
-
- // mark as patched
- mPatched = true;
-
- return noErr;
- }
-
-
- /* =============================================================================
- * Unpatch (private)
- *
- * Removes the patch that we installed for this mouse.
- * ========================================================================== */
- OSStatus ISpUSBDevice::Unpatch(void)
- {
- OSStatus err = noErr;
-
- WARNING(mPatched == true, "ISpUSBDevice Unpatch called but were are not patched!");
-
- if (0 != mHIDModuleDispatchTable)
- {
- // Install our handler
- err = (*mHIDModuleDispatchTable->pUHIDInstallInterrupt)(mUHIDConnectionID, nil, 0);
- WARNING(err == noErr, "USBDevice UHIDInstallInterrupt failed in Unpatch");
-
- err = (*mHIDModuleDispatchTable->pUHIDReleaseDevice)(mUHIDConnectionID);
- WARNING(err == noErr, "USBDevice UHIDReleaseDevice failed in Unpatch");
- }
-
- // mark as unpatched
- mPatched = false;
-
- return err;
- }
-
- /* =============================================================================
- * MyUHIDInterruptProc (local, c)
- *
- * This routine is called by the UHIDModule when there is an interupt packet.
- * ========================================================================== */
- void MyUHIDInterruptProc (void *theData, UInt32 refcon)
- {
- ISpUSBDevice* usbDeviceProCore = (ISpUSBDevice*) refcon;
- WARNING(usbDeviceProCore != nil, "USBDevice: patch object pointer was null");
-
- if (usbDeviceProCore != nil)
- { usbDeviceProCore->ParseData((Ptr)theData); }
- }
-
- inline void ISpUSBDevice::HandleDisappearedDevice(USBDeviceNotificationParameterBlockPtr passedPB)
- {
- #pragma unused ( passedPB )
- if (this->mUSBDeviceRef == passedPB->usbDeviceRef)
- this->mHIDModuleDispatchTable = 0; // remove references to now gone device
- }
-
- /* =============================================================================
- * UIDNotifyProc
- *
- * This routine is called by the the USB manager when we get a notify callback.
- * ========================================================================== */
- void ISpUSBDevice::UIDNotifyProc(USBDeviceNotificationParameterBlockPtr passedPB)
- {
- ISpUSBDevice* usbDeviceProCore = (ISpUSBDevice*) passedPB->refcon;
- WARNING(usbDeviceProCore != nil, "USBDevice: notify object pointer was null");
-
- // We must check the type of callback since even though we only registered for driver gone callbacks.
- // This is due to Radar bug #2248893.
-
- if (0 != usbDeviceProCore &&
- kNotifyRemoveInterface == passedPB->usbDeviceNotification) // our device removed
- {
- usbDeviceProCore->HandleDisappearedDevice(passedPB);
- }
- }
-
- OSStatus ISpUSBDevice::Init(UInt32 count, ISpNeed needs[], ISpElementReference virtualElements[],
- Boolean used[], OSType appCreatorCode, OSType subCreatorCode,
- UInt32 reserved, void* reserved2)
- {
- // dont use these four
- #pragma unused (appCreatorCode)
- #pragma unused (subCreatorCode)
- #pragma unused (reserved)
- #pragma unused (reserved2)
-
- UInt32 itr;
-
- // allocate arrays to hold references and needs and copy the data in
- mReferences = (ISpElementReference *) NewPtrSysClear(count * sizeof(ISpElementReference));
- WARNING(mReferences != nil, "ISpUSBDevice::Init failed to allocate mReferences");
- if (mReferences == nil) { return -1; }
-
- mNeeds = (ISpNeed *) NewPtrSysClear(count * sizeof(ISpNeed));
- WARNING(mNeeds != nil, "ISpUSBDevice::Init failed to allocate mNeeds");
- if (mNeeds == nil)
- {
- DisposePtr((Ptr) mReferences);
- mReferences = nil;
- return - 1;
- }
-
- mNumNeeds = count;
-
- // copy the data
- for(itr = 0; itr < count; itr++)
- {
- mReferences[itr] = virtualElements[itr];
- mNeeds[itr] = needs[itr];
- }
-
- // zero high level data
- mCurHLData.xAxis = mCurHLData.yAxis = mCurHLData.rudder = kISpAxisMiddle; // symetric axis
- mCurHLData.trim = mCurHLData.throttle = kISpAxisMiddle; // (since we allow buttons for both ends)
- mCurHLData.brake = mCurHLData.gas = kISpAxisMinimum; // asymetric axis
- for (UInt32 button_itr = 0; button_itr < kMaxHighLevelButtons; button_itr++)
- mCurHLData.buttons[button_itr] = kISpButtonUp;
- for (UInt32 dpad_itr = 0; dpad_itr < kMaxHighLevelDpads; dpad_itr++)
- mCurHLData.dpads[dpad_itr] = kISpPadIdle;
- SetAsFields (mCurHLData);
- mOldHLData = mCurHLData;
-
- AutoConfigure(used); // sets mDialogItemToNeedMapping and the virtual elements
-
- mVirtualElementsValid = true;
- mDirty = false;
-
- // set initial values
- SetAsFields (mOldHLData);
- PushDataToVirtuals (mOldHLData);
-
- return noErr;
- }
-
- void ISpUSBDevice::AutoConfigure(Boolean used[])
- {
- // mVirtualElement might not be valid yet
- WARNING(mNeeds != nil, "ISpUSBDevice::AutoConfigure mNeeds was nil");
- WARNING(used != nil, "ISpUSBDevice::AutoConfigure used was nil");
- WARNING(mDialogItemToNeedMapping != nil, "ISpUSBDevice::AutoConfigure mDialogItemToNeepMapping was nil");
-
- // clear out all the entries
- UInt32 itr;
- for(itr = 0; itr <= kDialogItem_NumPopups; itr++)
- { mDialogItemToNeedMapping[itr] = kUnsetIndex; }
-
- // AutoConfigure reads from mNeeds, mNumNeeds and sets mDialogItemToNeedMapping
-
- // we use this array to track which needs we've assigned (we handle case where this fails)
- Boolean * assigned = (Boolean *) NewPtrSysClear (mNumNeeds * sizeof(Boolean));
-
- // only make one pass if we failed to allocate assigned array
- UInt32 numPasses;
- numPasses = (assigned == nil) ? 1 : 2;
-
- // we'll do a two pass method, the first pass we'll only assign exact matches
- // the second pass we'll assign things that are close
- UInt32 pass;
- for (pass = 1; pass <= numPasses; pass++)
- {
- Boolean onlyExactMatches = true;
- if (pass == numPasses) // don't need exact match if last pass
- onlyExactMatches = false;
-
- for (UInt32 itr = 0; itr < mNumNeeds; itr++)
- {
- Boolean configured = false;
-
- // skip this need if we assigned it in the last pass
- if (assigned != nil)
- if (assigned[itr])
- continue;
-
- // we don't autoconfig to utility needs
- if (mNeeds[itr].flags & kISpNeedFlag_Utility)
- continue;
-
- if (used[itr] && (mNeeds[itr].flags & kISpNeedFlag_NoMultiConfig))
- continue;
-
- switch(mNeeds[itr].theKind)
- {
- case kISpElementKind_Button:
- if (TryButtonConfig (itr, onlyExactMatches))
- configured = true;
- break;
-
- case kISpElementKind_Axis:
- if (TryAxisConfig (itr, onlyExactMatches))
- configured = true;
- break;
-
- case kISpElementKind_DPad:
- if (TryDPadConfig (itr, onlyExactMatches))
- configured = true;
- else if (!onlyExactMatches)
- {
- if (TryStickConfig (itr, onlyExactMatches))
- configured = true;
- }
- break;
-
- case kISpElementKind_Movement:
- if (TryStickConfig (itr, onlyExactMatches))
- configured = true;
- else if (!onlyExactMatches)
- {
- if (TryDPadConfig (itr, onlyExactMatches))
- configured = true;
- }
- break;
- }
-
- if (configured)
- {
- if (assigned != nil)
- assigned[itr] = true;
-
- used[itr] = true;
- }
-
- }
- }
-
- if (assigned != nil)
- DisposePtr((Ptr) assigned);
-
- // assign the high level level elements
- SetVirtualElements ();
- }
-
- Boolean ISpUSBDevice::TryButtonConfig (UInt32 inNeedIndex, Boolean inOnlyExactMatch)
- {
- Boolean configured = false;
-
- switch(mNeeds[inNeedIndex].theLabel)
- {
- case kISpElementLabel_Btn_SlideLeft:
- case kISpElementLabel_Btn_LookLeft:
- case kISpElementLabel_Btn_TurnLeft:
- if (!inOnlyExactMatch && features.hasXAxis &&
- mDialogItemToNeedMapping[kDialogItem_StickLeft] == kUnsetIndex)
- {
- configured = true;
- mDialogItemToNeedMapping[kDialogItem_StickLeft] = inNeedIndex;
- }
- break;
-
- case kISpElementLabel_Btn_SlideRight:
- case kISpElementLabel_Btn_TurnRight:
- case kISpElementLabel_Btn_LookRight:
- if (!inOnlyExactMatch && features.hasXAxis &&
- mDialogItemToNeedMapping[kDialogItem_StickRight] == kUnsetIndex)
- {
- configured = true;
- mDialogItemToNeedMapping[kDialogItem_StickRight] = inNeedIndex;
- }
- break;
-
- case kISpElementLabel_Btn_MoveForward:
- case kISpElementLabel_Btn_LookUp:
- if (!inOnlyExactMatch && features.hasYAxis &&
- mDialogItemToNeedMapping[kDialogItem_StickUp] == kUnsetIndex)
- {
- configured = true;
- mDialogItemToNeedMapping[kDialogItem_StickUp] = inNeedIndex;
- }
- break;
-
- case kISpElementLabel_Btn_MoveBackward:
- case kISpElementLabel_Btn_LookDown:
- if (!inOnlyExactMatch && features.hasYAxis &&
- mDialogItemToNeedMapping[kDialogItem_StickDown] == kUnsetIndex)
- {
- configured = true;
- mDialogItemToNeedMapping[kDialogItem_StickDown] = inNeedIndex;
- }
- break;
-
- case kISpElementLabel_Btn_Fire:
- if (features.triggerButtonIndex != kUnsetIndex &&
- mDialogItemToNeedMapping[kDialogItem_Button1 + features.triggerButtonIndex] == kUnsetIndex)
- {
- configured = true;
- mDialogItemToNeedMapping[kDialogItem_Button1 + features.triggerButtonIndex] = inNeedIndex;
- }
- break;
-
- case kISpElementLabel_Btn_PauseResume:
- if (features.startButtonIndex != kUnsetIndex &&
- mDialogItemToNeedMapping[kDialogItem_Button1 + features.startButtonIndex] == kUnsetIndex)
- {
- configured = true;
- mDialogItemToNeedMapping[kDialogItem_Button1 + features.startButtonIndex] = inNeedIndex;
- }
- break;
-
- case kISpElementLabel_Btn_Select:
- if (features.selectButtonIndex != kUnsetIndex &&
- mDialogItemToNeedMapping[kDialogItem_Button1 + features.selectButtonIndex] == kUnsetIndex)
- {
- configured = true;
- mDialogItemToNeedMapping[kDialogItem_Button1 + features.selectButtonIndex] = inNeedIndex;
- }
- break;
-
- default:
- // we handle this case below
- break;
- }
-
- // if unconfigured, and not exact match, we just map to any unassigned button
- if (!configured && !inOnlyExactMatch)
- // don't configure axis or delta versions of buttons that did not have direction set...
- // they probably don't make sense for autoconfiguring
- if (!(mNeeds[inNeedIndex].flags & kISpNeedFlag_Button_AlreadyDelta) &&
- !(mNeeds[inNeedIndex].flags & kISpNeedFlag_Button_AlreadyAxis) )
- {
- UInt32 orderedIndex, buttonIndex;
-
- // first try to match ordered buttons
- for (orderedIndex = 0; orderedIndex < mNumOrderedButtons && !configured; orderedIndex++)
- {
- buttonIndex = mOrderedButtonsIndecies[orderedIndex];
-
- if (mDialogItemToNeedMapping[kDialogItem_Button1 + buttonIndex] == kUnsetIndex)
- {
- configured = true;
- mDialogItemToNeedMapping[kDialogItem_Button1 + buttonIndex] = inNeedIndex;
- }
- }
-
- // now match anything
- for (buttonIndex = 0; buttonIndex < features.numButtons && !configured; buttonIndex++)
- {
- if (mDialogItemToNeedMapping[kDialogItem_Button1 + buttonIndex] == kUnsetIndex)
- {
- configured = true;
- mDialogItemToNeedMapping[kDialogItem_Button1 + buttonIndex] = inNeedIndex;
- }
- }
- }
-
- return configured;
- }
-
- Boolean ISpUSBDevice::TryAxisConfig (UInt32 inNeedIndex, Boolean inOnlyExactMatch)
- {
- Boolean configured = false;
-
- switch (mNeeds[inNeedIndex].theLabel)
- {
- case kISpElementLabel_Axis_Rz:
- case kISpElementLabel_Axis_XAxis:
- if (TryStickXAxisConfig (inNeedIndex))
- configured = true;
- else if (!inOnlyExactMatch)
- {
- if (TryRudderConfig (inNeedIndex))
- configured = true;
- else if (TryDPadXAxisConfig (inNeedIndex))
- configured = true;
- }
- break;
-
- case kISpElementLabel_Axis_Rx:
- case kISpElementLabel_Axis_YAxis:
- if (TryStickYAxisConfig (inNeedIndex))
- configured = true;
- else if (!inOnlyExactMatch)
- {
- if (TryTrimConfig (inNeedIndex))
- configured = true;
- else if (TryDPadYAxisConfig (inNeedIndex))
- configured = true;
- }
- break;
-
- case kISpElementLabel_Axis_ZAxis:
- if (!inOnlyExactMatch)
- {
- if (TryTrimConfig (inNeedIndex))
- configured = true;
- else if (TryStickYAxisConfig (inNeedIndex))
- configured = true;
- else if (TryDPadYAxisConfig (inNeedIndex))
- configured = true;
- }
- break;
-
- case kISpElementLabel_Axis_Throttle:
- if (TryThrottleConfig (inNeedIndex))
- configured = true;
- else if (!inOnlyExactMatch)
- {
- if (TryTrimConfig (inNeedIndex))
- configured = true;
- else if (TryDPadYAxisConfig (inNeedIndex))
- configured = true;
- }
- break;
-
- case kISpElementLabel_Axis_Trim:
- if (TryTrimConfig (inNeedIndex))
- configured = true;
- else if (!inOnlyExactMatch)
- {
- if (TryDPadYAxisConfig (inNeedIndex))
- configured = true;
- }
- break;
-
- case kISpElementLabel_Axis_Ry:
- case kISpElementLabel_Axis_Rudder:
- if (TryRudderConfig (inNeedIndex))
- configured = true;
- else if (!inOnlyExactMatch)
- {
- if (TryStickXAxisConfig (inNeedIndex))
- configured = true;
- else if (TryDPadXAxisConfig (inNeedIndex))
- configured = true;
- }
- break;
-
- case kISpElementLabel_Axis_Gas:
- if (TryGasConfig (inNeedIndex))
- configured = true;
- else if (!inOnlyExactMatch)
- {
- if (TryThrottleConfig (inNeedIndex))
- configured = true;
- }
- break;
-
- case kISpElementLabel_Axis_Brake:
- if (TryBrakeConfig (inNeedIndex))
- configured = true;
- break;
-
- }
-
- return configured;
- }
-
- Boolean ISpUSBDevice::TryDPadConfig (UInt32 inNeedIndex, Boolean inOnlyExactMatch)
- {
- inOnlyExactMatch; // not used (we only check for exact matches
-
- Boolean configured = false;
-
- // we make to passes, so as to prefer 8-way hats
- for (UInt32 pass = 1; pass <= 2; pass++)
- for (UInt32 dpadIndex = 0; dpadIndex < features.numDPads && !configured; dpadIndex++)
- {
- // on first pass, only configure 8-way hats
- if ((!features.is4WayDPad[dpadIndex] || pass == 2) &&
- (mDialogItemToNeedMapping[kDialogItem_DPad1Up + (dpadIndex * 4)] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_DPad1Left + (dpadIndex * 4)] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_DPad1Down + (dpadIndex * 4)] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_DPad1Right + (dpadIndex * 4)] == kUnsetIndex))
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_DPad1Up + (dpadIndex * 4)] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_DPad1Left + (dpadIndex * 4)] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_DPad1Down + (dpadIndex * 4)] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_DPad1Right + (dpadIndex * 4)] = inNeedIndex;
- }
- }
-
- return configured;
- }
-
- Boolean ISpUSBDevice::TryStickConfig (UInt32 inNeedIndex, Boolean inOnlyExactMatch)
- {
- inOnlyExactMatch; // not used (we only check for exact matches
-
- Boolean configured = false;
-
- if (features.hasXAxis && features.hasYAxis &&
- (mDialogItemToNeedMapping[kDialogItem_StickUp] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_StickDown] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_StickLeft] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_StickRight] == kUnsetIndex))
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_StickUp] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_StickLeft] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_StickDown] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_StickRight] = inNeedIndex;
- }
-
- return configured;
- }
-
- Boolean ISpUSBDevice::TryStickXAxisConfig (UInt32 inNeedIndex)
- {
- Boolean configured = false;
-
- if (features.hasXAxis &&
- (mDialogItemToNeedMapping[kDialogItem_StickLeft] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_StickRight] == kUnsetIndex))
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_StickLeft] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_StickRight] = inNeedIndex;
- }
-
- return configured;
-
- }
-
- Boolean ISpUSBDevice::TryStickYAxisConfig (UInt32 inNeedIndex)
- {
- Boolean configured = false;
-
- if (features.hasYAxis &&
- (mDialogItemToNeedMapping[kDialogItem_StickUp] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_StickDown] == kUnsetIndex))
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_StickUp] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_StickDown] = inNeedIndex;
- }
-
- return configured;
-
- }
-
- Boolean ISpUSBDevice::TryDPadXAxisConfig (UInt32 inNeedIndex)
- {
- Boolean configured = false;
-
- for (UInt32 dpadIndex = 0; dpadIndex < features.numDPads && !configured; dpadIndex++)
- {
- if ((mDialogItemToNeedMapping[kDialogItem_DPad1Left + (dpadIndex * 4)] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_DPad1Right + (dpadIndex * 4)] == kUnsetIndex))
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_DPad1Left + (dpadIndex * 4)] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_DPad1Right + (dpadIndex * 4)] = inNeedIndex;
- }
- }
-
- return configured;
- }
-
- Boolean ISpUSBDevice::TryDPadYAxisConfig (UInt32 inNeedIndex)
- {
- Boolean configured = false;
-
- for (UInt32 dpadIndex = 0; dpadIndex < features.numDPads && !configured; dpadIndex++)
- {
- if ((mDialogItemToNeedMapping[kDialogItem_DPad1Up + (dpadIndex * 4)] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_DPad1Down + (dpadIndex * 4)] == kUnsetIndex))
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_DPad1Up + (dpadIndex * 4)] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_DPad1Down + (dpadIndex * 4)] = inNeedIndex;
- }
- }
-
- return configured;
- }
-
- Boolean ISpUSBDevice::TryTrimConfig (UInt32 inNeedIndex)
- {
- Boolean configured = false;
-
- if (features.hasTrim &&
- (mDialogItemToNeedMapping[kDialogItem_TrimHigher] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_TrimLower] == kUnsetIndex))
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_TrimHigher] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_TrimLower] = inNeedIndex;
- }
-
- return configured;
- }
-
- Boolean ISpUSBDevice::TryThrottleConfig (UInt32 inNeedIndex)
- {
- Boolean configured = false;
-
- if (features.hasThrottle &&
- (mDialogItemToNeedMapping[kDialogItem_ThrottleHigher] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_ThrottleLower] == kUnsetIndex))
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_ThrottleHigher] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_ThrottleLower] = inNeedIndex;
- }
-
- return configured;
- }
-
- Boolean ISpUSBDevice::TryRudderConfig (UInt32 inNeedIndex)
- {
- Boolean configured = false;
-
- if (features.hasRudder &&
- (mDialogItemToNeedMapping[kDialogItem_RudderLeft] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_RudderRight] == kUnsetIndex))
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_RudderLeft] = inNeedIndex;
- mDialogItemToNeedMapping[kDialogItem_RudderRight] = inNeedIndex;
- }
-
- return configured;
- }
-
- Boolean ISpUSBDevice::TryGasConfig (UInt32 inNeedIndex)
- {
- Boolean configured = false;
-
- if (features.hasGas &&
- mDialogItemToNeedMapping[kDialogItem_GasDepressed] == kUnsetIndex)
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_GasDepressed] = inNeedIndex;
- }
-
- return configured;
- }
-
- Boolean ISpUSBDevice::TryBrakeConfig (UInt32 inNeedIndex)
- {
- Boolean configured = false;
-
- if (features.hasBrake &&
- mDialogItemToNeedMapping[kDialogItem_BrakeDepressed] == kUnsetIndex)
- {
- configured = true;
-
- mDialogItemToNeedMapping[kDialogItem_BrakeDepressed] = inNeedIndex;
- }
-
- return configured;
- }
-
- OSStatus ISpUSBDevice::Stop(void)
- {
- // need to mark mVirtualElementValid as false first
- mVirtualElementsValid = false;
-
- if (mReferences) DisposePtr((Ptr) mReferences);
- mReferences = nil;
-
- if (mNeeds) DisposePtr((Ptr) mNeeds);
- mNeeds = nil;
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::HandleEvent(EventRecord &theEvent, Boolean &handled)
- {
- theEvent;
-
- handled = false;
-
- UpdateAllButtons();
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::Show(DialogPtr theDialog, short dialogItemNumber, Rect &r)
- {
- mRect = r;
-
- mBaseDITLCount = CountDITL(theDialog);
- mResRef = FSpOpenResFile(&mFileSpec, fsRdPerm);
- RES_WARNING("\pcould not FSpOpenResFile on the Joy ResFile");
-
- Handle ditl = Get1Resource('DITL', GetDeviceResID());
- RES_WARNING("\pcould not Get1Resource on the Joy DITL");
-
- mDialog = theDialog;
- mVisable = true;
-
- AppendDITL(theDialog, ditl, -dialogItemNumber);
- ReleaseResource(ditl);
-
- // x & y axis
- if (!features.hasXAxis)
- {
- MakeDialogItemInvisable (theDialog, kDialogItem_StickLeft + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_StickRight + mBaseDITLCount);
- if (!features.hasYAxis)
- MakeDialogItemInvisable (theDialog, kDialogItem_Stick_Label + mBaseDITLCount);
- }
- if (!features.hasYAxis)
- {
- MakeDialogItemInvisable (theDialog, kDialogItem_StickUp + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_StickDown + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_ReverseStick + mBaseDITLCount);
- }
- else
- SetDialogControl(kDialogItem_ReverseStick, mReverseStick);
-
- // trim
- if (!features.hasTrim)
- {
- MakeDialogItemInvisable (theDialog, kDialogItem_TrimLower + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_TrimHigher + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_Trim_Label + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_ReverseTrim + mBaseDITLCount);
- }
- else
- SetDialogControl(kDialogItem_ReverseTrim, mReverseTrim);
-
- // throttle
- if (!features.hasThrottle)
- {
- MakeDialogItemInvisable (theDialog, kDialogItem_ThrottleLower + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_ThrottleHigher + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_Throttle_Label + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_ReverseThrottle + mBaseDITLCount);
- }
- else
- SetDialogControl(kDialogItem_ReverseThrottle, mReverseThrottle);
-
- // rudder
- if (!features.hasRudder)
- {
- MakeDialogItemInvisable (theDialog, kDialogItem_RudderLeft + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_RudderRight + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_Rudder_Label + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_ReverseRudder + mBaseDITLCount);
- }
- else
- SetDialogControl(kDialogItem_ReverseRudder, mReverseRudder);
-
- // brake
- if (!features.hasBrake)
- {
- MakeDialogItemInvisable (theDialog, kDialogItem_BrakeDepressed + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_Brake_Label + mBaseDITLCount);
- }
- // obsolete ditem
- MakeDialogItemInvisable (theDialog, kDialogItem_BrakeNotUsed + mBaseDITLCount);
-
- // gas
- if (!features.hasGas)
- {
- MakeDialogItemInvisable (theDialog, kDialogItem_GasDepressed + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_Gas_Label + mBaseDITLCount);
- }
- // obsolete ditem
- MakeDialogItemInvisable (theDialog, kDialogItem_GasNotUsed + mBaseDITLCount);
-
- // buttons
- if (features.numButtons < kMaxHighLevelButtons )
- {
- UInt32 buttonsToRemove = kMaxHighLevelButtons - features.numButtons;
- while (buttonsToRemove--)
- MakeDialogItemInvisable (theDialog, kDialogItem_Button12 - buttonsToRemove + mBaseDITLCount);
-
- if (features.numButtons == 0)
- MakeDialogItemInvisable (theDialog, kDialogItem_Buttons_Label + mBaseDITLCount);
- }
-
- // dpads
- if (features.numDPads < kMaxHighLevelDpads )
- {
- UInt32 itemsToRemove = kMaxHighLevelDpads - features.numDPads;
- while (itemsToRemove--)
- {
- MakeDialogItemInvisable (theDialog, kDialogItem_DPad4Up - (itemsToRemove * 4) + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_DPad4Left - (itemsToRemove * 4) + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_DPad4Down - (itemsToRemove * 4) + mBaseDITLCount);
- MakeDialogItemInvisable (theDialog, kDialogItem_DPad4Right - (itemsToRemove * 4) + mBaseDITLCount);
-
- MakeDialogItemInvisable (theDialog, kDialogItem_ReverseDPad4 - itemsToRemove + mBaseDITLCount);
- }
-
- if (features.numDPads == 0)
- MakeDialogItemInvisable (theDialog, kDialogItem_DPads_Label + mBaseDITLCount);
- }
-
- UInt32 index;
- for (index = 0; index < features.numDPads; index++)
- SetDialogControl(kDialogItem_ReverseDPad1 + index, mReverseDPad[index]);
-
- // clear out ui indiciators
- for (index = 0; index < kDialogItem_NumPopups; index++)
- mPopupPressed[index] = false;
- UpdateAllButtons ();
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::Hide(void)
- {
- // restore to original count of items
- ShortenDITL(mDialog, CountDITL(mDialog) - mBaseDITLCount);
- WARNING(CountDITL(mDialog) == mBaseDITLCount, "ISpUSBDevice::Hide Failed to restore the DITL count");
-
- // mark that we are no longer visable
- mVisable = false;
-
- // clear our mDialog ptr
- mDialog = nil;
-
- // close our res file and assert check
- CloseResFile(mResRef);
- RES_WARNING("ISpUSBDevice::Hide CloseResFile choked");
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::BeginConfiguration(UInt32 count, ISpNeed needs[])
- {
- #pragma unused(count)
- #pragma unused(needs)
-
- WARNING(mVirtualElementsValid, "BeginConfiguration was called but the virtual elements were not valid");
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::EndConfiguration(Boolean accept)
- {
- accept;
-
- WARNING(mVirtualElementsValid, "EndConfiguration was called but the virtual elements were not valid");
-
- SetVirtualElements();
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::SetActive(Boolean active)
- {
- if (mActive == active) return noErr;
-
- mActive = active;
-
- // we're responsible for pushing any values which are non-default
- if (mActive) PushAllNonDefaultValues();
-
- return noErr;
- }
-
- /* =============================================================================
- * PushAllNonDefaultValues (private)
- *
- * This is done when activating, as part of our duties as the driver.
- *
- * A driver is responsible for pushing all non-default values when it is
- * activated.
- *
- * the default values for buttons, dpads, deltas and asymmetric axis is zero
- * the default value for symmetric axis is kISpAxisMiddle
- *
- * ========================================================================== */
- OSStatus ISpUSBDevice::PushAllNonDefaultValues(void)
- {
- OSStatus err = noErr;
- AbsoluteTime time = ISpUptime ();
-
- // set all the 'old' values for axis elements to the reset value
- for (UInt32 itr = 0; itr < mUSBElementCount; itr++)
- {
- // if this is a valid axis then read the data
- if ((mUSBMapping[itr].kind == kISpElementKind_Axis) && (mUSBMapping[itr].valid))
- {
- UInt32 resetAxisValue = kISpAxisMinimum;
- if (mUSBMapping[itr].flags & kMappingFlag_AxisIsSymmetric)
- resetAxisValue = kISpAxisMiddle;
-
- mUSBMapping[itr].lastValue = resetAxisValue;
-
- err = ISpElement_PushSimpleData(mUSBMapping[itr].element, resetAxisValue, &time);
- }
- }
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::GetIcon(short &iconSuiteResourceId)
- {
- iconSuiteResourceId = GetDeviceResID ();
-
- return 0;
- }
-
-
- void ISpUSBDevice::DoReverse(short dialog_item, Boolean &the_boolean)
- {
- the_boolean = !the_boolean;
- SetDialogControl(dialog_item, the_boolean);
- mDirty = true;
- }
-
-
- OSStatus ISpUSBDevice::DialogItemHit(short itemHit)
- {
- short relHit = itemHit - mBaseDITLCount;
-
- switch (relHit)
- {
- case kDialogItem_ReverseStick: DoReverse(relHit, mReverseStick); break;
- case kDialogItem_ReverseTrim: DoReverse(relHit, mReverseTrim); break;
- case kDialogItem_ReverseThrottle: DoReverse(relHit, mReverseThrottle); break;
- case kDialogItem_ReverseRudder: DoReverse(relHit, mReverseRudder); break;
- case kDialogItem_ReverseDPad1: DoReverse(relHit, mReverseDPad[0]); break;
- case kDialogItem_ReverseDPad2: DoReverse(relHit, mReverseDPad[1]); break;
- case kDialogItem_ReverseDPad3: DoReverse(relHit, mReverseDPad[2]); break;
- case kDialogItem_ReverseDPad4: DoReverse(relHit, mReverseDPad[3]); break;
- }
-
- return noErr;
- }
-
-
- OSStatus ISpUSBDevice::GetState(UInt32 buflen, void *buffer, UInt32 &length)
- {
- WARNING(mVirtualElementsValid, "ISpUSBDevice: GetState was called but the virtual elemtns were not valid");
- WARNING((buflen == 0) || (buffer != nil), "ISpUSBDevice: GetState buffer == nil");
-
- USBSetVersion1 *set_vers1_ptr = (USBSetVersion1 *) buffer;
- length = sizeof(USBSetVersion1);
-
- if (length > buflen) { return noErr; } // required length > space in the buffer, return
-
- UInt32 itr;
- set_vers1_ptr->version = kSetVersion1;
-
- for(itr = 1; itr <= kDialogItem_NumPopups; itr++)
- {
- set_vers1_ptr->mapping[itr - 1] = mDialogItemToNeedMapping[itr]; // set is zero based array
- }
-
- set_vers1_ptr->flags = 0;
-
- if (mReverseStick) { set_vers1_ptr->flags |= kSetReverseStick; }
- if (mReverseTrim) { set_vers1_ptr->flags |= kSetReverseTrim; }
- if (mReverseThrottle) { set_vers1_ptr->flags |= kSetReverseThrottle; }
- if (mReverseRudder) { set_vers1_ptr->flags |= kSetReverseRudder; }
- if (mReverseDPad[0]) { set_vers1_ptr->flags |= kSetReverseDPad1; }
- if (mReverseDPad[1]) { set_vers1_ptr->flags |= kSetReverseDPad2; }
- if (mReverseDPad[2]) { set_vers1_ptr->flags |= kSetReverseDPad3; }
- if (mReverseDPad[3]) { set_vers1_ptr->flags |= kSetReverseDPad4; }
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::SetState(UInt32 length, void *buffer)
- {
- WARNING(mVirtualElementsValid, "SetState was called but the virtual elements were not valid");
- WARNING((length == 0) || (buffer != nil), "ISpUSBDevice: SetState buffer == nil");
- WARNING((length > 4), "ISpUSBDevice: SetState length < 4");
-
- UInt32 itr;
-
- // min size check
- if (length < 4) { return -1;}
-
- UInt32 version = * ((UInt32 *) buffer);
-
- switch(version)
- {
- case kSetVersion1:
- if (length == sizeof(USBSetVersion1))
- {
- USBSetVersion1 *set_vers1_ptr = (USBSetVersion1 *) buffer;
-
- for(itr = 1; itr <= kDialogItem_NumPopups; itr++)
- {
- mDialogItemToNeedMapping[itr] = set_vers1_ptr->mapping[itr - 1]; // set is zero based array
- }
-
- mReverseStick = (set_vers1_ptr->flags & kSetReverseStick) > 0;
- mReverseTrim = (set_vers1_ptr->flags & kSetReverseTrim) > 0;
- mReverseThrottle = (set_vers1_ptr->flags & kSetReverseThrottle) > 0;
- mReverseRudder = (set_vers1_ptr->flags & kSetReverseRudder) > 0;
- mReverseDPad[0] = (set_vers1_ptr->flags & kSetReverseDPad1) > 0;
- mReverseDPad[1] = (set_vers1_ptr->flags & kSetReverseDPad2) > 0;
- mReverseDPad[2] = (set_vers1_ptr->flags & kSetReverseDPad3) > 0;
- mReverseDPad[3] = (set_vers1_ptr->flags & kSetReverseDPad4) > 0;
- }
- break;
- }
-
- SetVirtualElements();
-
- if (mVisable)
- {
- Draw ();
-
-
- if (features.hasYAxis)
- SetDialogControl(kDialogItem_ReverseStick, mReverseStick);
-
- if (features.hasTrim)
- SetDialogControl(kDialogItem_ReverseTrim, mReverseTrim);
-
- if (features.hasThrottle)
- SetDialogControl(kDialogItem_ReverseThrottle, mReverseThrottle);
-
- if (features.hasRudder)
- SetDialogControl(kDialogItem_ReverseRudder, mReverseRudder);
-
- UInt32 index;
- for (index = 0; index < features.numDPads; index++)
- SetDialogControl(kDialogItem_ReverseDPad1 + index, mReverseDPad[index]);
- }
-
- mDirty = false;
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::Tickle(void)
- {
- return noErr;
- }
-
- void ISpUSBDevice::SetAsFields(HighLevelData ¤t)
- {
- AxisToButtons(current.xAxis, current.xAxis_as_buttons);
- AxisToButtons(current.yAxis, current.yAxis_as_buttons);
- AxisToButtons(current.trim, current.trim_as_buttons);
- AxisToButtons(current.throttle, current.throttle_as_buttons);
- AxisToButtons(current.rudder, current.rudder_as_buttons);
-
- PedalAxisToButton(current.brake, current.brake_as_button);
- PedalAxisToButton(current.gas, current.gas_as_button);
-
- UInt32 itr;
- for(itr = 0; itr < features.numDPads; itr++)
- {
- DPadToButtonsAndAxis (current.dpads[itr], current.dpads_as_buttons[itr], current.dpads_as_axis[itr]);
- }
- }
-
- void ISpUSBDevice::PushDataToVirtuals(HighLevelData ¤t)
- {
- if (mVirtualElementsValid == false)
- return;
-
- OSStatus err;
- AbsoluteTime time = ISpUptime ();
-
- // x and y axis
- if ((features.hasXAxis) && (features.hasYAxis))
- {
- if (((current.xAxis != mOldHLData.xAxis) || (current.yAxis != mOldHLData.yAxis)) &&
- (virtuals.stickMovement || virtuals.stickDPad) )
- {
- ISpMovementData moveData;
-
- moveData.xAxis = current.xAxis;
- moveData.yAxis = current.yAxis;
-
- moveData.direction = AxisToDPad(moveData.xAxis, moveData.yAxis);
-
- if (virtuals.stickMovement != nil)
- {
- err = ISpElement_PushComplexData(virtuals.stickMovement, sizeof (moveData), &moveData, &time);
- }
-
- if (virtuals.stickDPad != nil)
- {
- err = ISpElement_PushSimpleData(virtuals.stickDPad, moveData.direction, &time);
- }
- }
- }
-
- // *************** X AXIS ***************
- if (features.hasXAxis)
- {
- if ((current.xAxis != mOldHLData.xAxis) && (virtuals.xAxis != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.xAxis, current.xAxis, &time);
- }
-
- if ((current.xAxis_as_buttons[0] != mOldHLData.xAxis_as_buttons[0]) && (virtuals.xAxis_as_buttons[0] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.xAxis_as_buttons[0], current.xAxis_as_buttons[0], &time);
- }
-
- if ((current.xAxis_as_buttons[1] != mOldHLData.xAxis_as_buttons[1]) && (virtuals.xAxis_as_buttons[1] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.xAxis_as_buttons[1], current.xAxis_as_buttons[1], &time);
- }
- }
-
- // *************** Y AXIS ***************
- if (features.hasYAxis)
- {
- if ((current.yAxis != mOldHLData.yAxis) && (virtuals.yAxis != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.yAxis, current.yAxis, &time);
- }
-
- if ((current.yAxis_as_buttons[1] != mOldHLData.yAxis_as_buttons[1]) && (virtuals.yAxis_as_buttons[1] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.yAxis_as_buttons[1], current.yAxis_as_buttons[1], &time);
- }
-
- if ((current.yAxis_as_buttons[0] != mOldHLData.yAxis_as_buttons[0]) && (virtuals.yAxis_as_buttons[0] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.yAxis_as_buttons[0], current.yAxis_as_buttons[0], &time);
- }
- }
-
- // *************** TRIM ***************
- if (features.hasTrim)
- {
- if ((current.trim != mOldHLData.trim) && (virtuals.trim != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.trim, current.trim, &time);
- }
-
- if ((current.trim_as_buttons[0] != mOldHLData.trim_as_buttons[0]) && (virtuals.trim_as_buttons[0] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.trim_as_buttons[0], current.trim_as_buttons[0], &time);
- }
-
- if ((current.trim_as_buttons[1] != mOldHLData.trim_as_buttons[1]) && (virtuals.trim_as_buttons[1] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.trim_as_buttons[1], current.trim_as_buttons[1], &time);
- }
- }
-
- // *************** THROTTLE ***************
- if (features.hasThrottle)
- {
- if ((current.throttle != mOldHLData.throttle) && (virtuals.throttle != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.throttle, current.throttle, &time);
- }
-
- if ((current.throttle_as_buttons[0] != mOldHLData.throttle_as_buttons[0]) && (virtuals.throttle_as_buttons[0] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.throttle_as_buttons[0], current.throttle_as_buttons[0], &time);
- }
-
- if ((current.throttle_as_buttons[1] != mOldHLData.throttle_as_buttons[1]) && (virtuals.throttle_as_buttons[1] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.throttle_as_buttons[1], current.throttle_as_buttons[1], &time);
- }
- }
-
- // *************** RUDDER ***************
- if (features.hasRudder)
- {
- if ((current.rudder != mOldHLData.rudder) && (virtuals.rudder != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.rudder, current.rudder, &time);
- }
-
- if ((current.rudder_as_buttons[0] != mOldHLData.rudder_as_buttons[0]) && (virtuals.rudder_as_buttons[0] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.rudder_as_buttons[0], current.rudder_as_buttons[0], &time);
- }
-
- if ((current.rudder_as_buttons[1] != mOldHLData.rudder_as_buttons[1]) && (virtuals.rudder_as_buttons[1] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.rudder_as_buttons[1], current.rudder_as_buttons[1], &time);
- }
- }
-
- // *************** BRAKE ***************
- if (features.hasBrake)
- {
- if ((current.brake != mOldHLData.brake) && (virtuals.brake != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.brake, current.brake, &time);
- }
-
- if ((current.brake_as_button != mOldHLData.brake_as_button) && (virtuals.brake_as_button != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.brake_as_button, current.brake_as_button, &time);
- }
- }
-
- // *************** GAS ***************
- if (features.hasGas)
- {
- if ((current.gas != mOldHLData.gas) && (virtuals.gas != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.gas, current.gas, &time);
- }
-
- if ((current.gas_as_button != mOldHLData.gas_as_button) && (virtuals.gas_as_button != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.gas_as_button, current.gas_as_button, &time);
- }
- }
-
- // *************** DPADS ***************
- UInt32 dpad_itr;
- for(dpad_itr = 0; dpad_itr < features.numDPads; dpad_itr++)
- {
- if ((current.dpads[dpad_itr] != mOldHLData.dpads[dpad_itr]) && (virtuals.dpads[dpad_itr] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.dpads[dpad_itr], current.dpads[dpad_itr], &time);
- }
-
- UInt32 dpad_button_itr;
- for(dpad_button_itr = 0; dpad_button_itr < 4; dpad_button_itr++)
- {
- ISpElementReference this_dpad_button_element = virtuals.dpads_as_buttons[dpad_itr][dpad_button_itr];
- UInt32 cur_dpad_button_data = current.dpads_as_buttons[dpad_itr][dpad_button_itr];
- UInt32 old_dpad_button_data = mOldHLData.dpads_as_buttons[dpad_itr][dpad_button_itr];
-
- if ((cur_dpad_button_data != old_dpad_button_data) && (this_dpad_button_element != nil))
- {
- err = ISpElement_PushSimpleData(this_dpad_button_element, cur_dpad_button_data, &time);
- }
- }
-
- Boolean axisDataChanged = false;
-
- UInt32 dpad_axis_itr;
- for(dpad_axis_itr = 0; dpad_axis_itr < 2; dpad_axis_itr++)
- {
- ISpElementReference this_dpad_axis_element = virtuals.dpads_as_axis[dpad_itr][dpad_axis_itr];
- UInt32 cur_dpad_axis_data = current.dpads_as_axis[dpad_itr][dpad_axis_itr];
- UInt32 old_dpad_axis_data = mOldHLData.dpads_as_axis[dpad_itr][dpad_axis_itr];
-
- if (cur_dpad_axis_data != old_dpad_axis_data)
- {
- axisDataChanged = true;
-
- if (this_dpad_axis_element != nil)
- err = ISpElement_PushSimpleData(this_dpad_axis_element, cur_dpad_axis_data, &time);
- }
- }
-
- if (axisDataChanged && virtuals.dpads_as_movement[dpad_itr])
- {
- ISpMovementData moveData;
-
- moveData.xAxis = current.dpads_as_axis[dpad_itr][0];
- moveData.yAxis = current.dpads_as_axis[dpad_itr][1];
-
- moveData.direction = current.dpads[dpad_itr];
-
- if (virtuals.dpads_as_movement[dpad_itr] != nil)
- {
- err = ISpElement_PushComplexData(virtuals.dpads_as_movement[dpad_itr], sizeof (moveData), &moveData, &time);
- }
- }
-
- }
-
- // *************** BUTTONS ***************
- UInt32 button_itr;
- for(button_itr = 0; button_itr < features.numButtons; button_itr++)
- {
- if ((current.buttons[button_itr] != mOldHLData.buttons[button_itr]) && (virtuals.buttons[button_itr] != nil))
- {
- err = ISpElement_PushSimpleData(virtuals.buttons[button_itr], current.buttons[button_itr], &time);
- }
- }
-
- }
-
- OSStatus ISpUSBDevice::InterruptTickle(void)
- {
- return noErr;
- }
-
- OSStatus ISpUSBDevice::Draw(void)
- {
- UInt32 itr;
-
- for(itr = 0; itr < kDialogItem_NumPopups; itr++)
- {
- short itemNo = itr + kDialogItem_FirstPopup + mBaseDITLCount;
-
- PlotPopupIcon (itemNo, ttNone);
- }
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::Click(const EventRecord &event)
- {
- // Find the point in local coords
- Point where;
- where = event.where;
- GlobalToLocal(&where);
-
- UInt32 itr;
-
- for(itr = kDialogItem_FirstPopup; itr <= kDialogItem_NumPopups; itr++)
- {
- short itemNo = itr + mBaseDITLCount;
- UInt32 oldNeed = mDialogItemToNeedMapping[itr];
- UInt32 newNeed;
-
- switch (itr)
- {
- case kDialogItem_StickLeft:
- case kDialogItem_StickRight:
- // handle as stick (both axis present)
- if (features.hasXAxis && features.hasYAxis)
- HandleStickClick (where, itemNo,
- kDialogItem_StickUp, kDialogItem_StickDown,
- kDialogItem_StickLeft, kDialogItem_StickRight, oldNeed, newNeed);
- // handle as axis (both axis not present)
- else if (features.hasXAxis)
- HandleAxisClick (where, itemNo, kISpElementLabel_Axis_XAxis,
- kDialogItem_StickLeft, kDialogItem_StickRight, oldNeed, newNeed);
- break;
-
- case kDialogItem_StickUp:
- case kDialogItem_StickDown:
- // handle as stick (both axis present)
- if (features.hasXAxis && features.hasYAxis)
- HandleStickClick (where, itemNo,
- kDialogItem_StickUp, kDialogItem_StickDown,
- kDialogItem_StickLeft, kDialogItem_StickRight, oldNeed, newNeed);
- // handle as axis (both axis not present)
- else if (features.hasYAxis)
- HandleAxisClick (where, itemNo, kISpElementLabel_Axis_YAxis,
- kDialogItem_StickDown, kDialogItem_StickUp, oldNeed, newNeed);
- break;
-
- case kDialogItem_TrimLower:
- case kDialogItem_TrimHigher:
- if (features.hasTrim)
- HandleAxisClick (where, itemNo, kISpElementLabel_Axis_Trim,
- kDialogItem_TrimLower, kDialogItem_TrimHigher, oldNeed, newNeed);
- break;
-
- case kDialogItem_ThrottleLower:
- case kDialogItem_ThrottleHigher:
- if (features.hasThrottle)
- HandleAxisClick (where, itemNo, kISpElementLabel_Axis_Throttle,
- kDialogItem_ThrottleLower, kDialogItem_ThrottleHigher, oldNeed, newNeed);
- break;
-
- case kDialogItem_RudderLeft:
- case kDialogItem_RudderRight:
- if (features.hasRudder)
- HandleAxisClick (where, itemNo, kISpElementLabel_Axis_Rudder,
- kDialogItem_RudderLeft, kDialogItem_RudderRight, oldNeed, newNeed);
- break;
-
- case kDialogItem_BrakeDepressed:
- if (features.hasBrake)
- HandlePedalAxisClick (where, itemNo, kISpElementLabel_Axis_Brake,
- oldNeed, newNeed);
- break;
-
- case kDialogItem_GasDepressed:
- if (features.hasGas)
- HandlePedalAxisClick (where, itemNo, kISpElementLabel_Axis_Gas,
- oldNeed, newNeed);
- break;
-
- case kDialogItem_Button1:
- case kDialogItem_Button2:
- case kDialogItem_Button3:
- case kDialogItem_Button4:
- case kDialogItem_Button5:
- case kDialogItem_Button6:
- case kDialogItem_Button7:
- case kDialogItem_Button8:
- case kDialogItem_Button9:
- case kDialogItem_Button10:
- case kDialogItem_Button11:
- case kDialogItem_Button12:
- if (features.numButtons > itr - kDialogItem_Button1)
- HandleButtonClick (where, itemNo, kISpElementLabel_None, oldNeed, newNeed);
- break;
-
- case kDialogItem_DPad1Up:
- case kDialogItem_DPad1Left:
- case kDialogItem_DPad1Down:
- case kDialogItem_DPad1Right:
- if (features.numDPads >= 1)
- HandleDPadClick (where, itemNo, kDialogItem_DPad1Up, kDialogItem_DPad1Down,
- kDialogItem_DPad1Left, kDialogItem_DPad1Right, oldNeed, newNeed);
- break;
-
- case kDialogItem_DPad2Up:
- case kDialogItem_DPad2Left:
- case kDialogItem_DPad2Down:
- case kDialogItem_DPad2Right:
- if (features.numDPads >= 2)
- HandleDPadClick (where, itemNo, kDialogItem_DPad2Up, kDialogItem_DPad2Down,
- kDialogItem_DPad2Left, kDialogItem_DPad2Right, oldNeed, newNeed);
- break;
-
- case kDialogItem_DPad3Up:
- case kDialogItem_DPad3Left:
- case kDialogItem_DPad3Down:
- case kDialogItem_DPad3Right:
- if (features.numDPads >= 3)
- HandleDPadClick (where, itemNo, kDialogItem_DPad3Up, kDialogItem_DPad3Down,
- kDialogItem_DPad3Left, kDialogItem_DPad3Right, oldNeed, newNeed);
- break;
-
- case kDialogItem_DPad4Up:
- case kDialogItem_DPad4Left:
- case kDialogItem_DPad4Down:
- case kDialogItem_DPad4Right:
- if (features.numDPads >= 4)
- HandleDPadClick (where, itemNo, kDialogItem_DPad4Up, kDialogItem_DPad4Down,
- kDialogItem_DPad4Left, kDialogItem_DPad4Right, oldNeed, newNeed);
- break;
-
- default:
- break;
- }
- }
-
- return noErr;
- }
-
- OSStatus ISpUSBDevice::ADBReInit(Boolean inPostProcess)
- {
- #pragma unused (inPostProcess)
-
- return noErr;
- }
-
- /*
- *
- * SetVirtualElements
- *
- * This function takes the virtual index stuff and sets our virtual elements;
- *
- */
-
- void ISpUSBDevice::SetVirtualElements(void)
- {
- WARNING(mNeeds != nil, "ISpUSBDevice::SetVirtualElements but mNeeds was nil");
- WARNING(mReferences != nil, "ISpUSBDevice::SetVirtualElements but mReferences was nil");
- WARNING(mDialogItemToNeedMapping != nil, "ISpUSBDevice::SetVirtualElements but mDialogItemToNeedMapping was nil");
-
- #if DEBUG
- {
- UInt32 debug_mapping_itr;
-
- for(debug_mapping_itr = 0; debug_mapping_itr < kDialogItem_NumPopups+1; debug_mapping_itr++)
- {
- UInt32 debug_mapping = mDialogItemToNeedMapping[debug_mapping_itr];
- WARNING(((debug_mapping == kUnsetIndex) || (debug_mapping < mNumNeeds)), "ISpUSBDevice::SetVirtualElements out of range");
- }
- }
- #endif
-
- ClearVirtuals ();
-
- UInt32 need;
-
- // stick up: up button, y axis and movement
- need = mDialogItemToNeedMapping[kDialogItem_StickUp];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Movement: virtuals.stickMovement = mReferences[need]; break;
- case kISpElementKind_DPad: virtuals.stickDPad = mReferences[need]; break;
- case kISpElementKind_Axis: virtuals.yAxis = mReferences[need]; break;
- case kISpElementKind_Button: virtuals.yAxis_as_buttons[1] = mReferences[need]; break;
- }
- }
-
- // stick down: down button
- need = mDialogItemToNeedMapping[kDialogItem_StickDown];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: virtuals.yAxis_as_buttons[0] = mReferences[need]; break;
- }
- }
-
- // stick left: left button and x axis
- need = mDialogItemToNeedMapping[kDialogItem_StickLeft];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: virtuals.xAxis = mReferences[need]; break;
- case kISpElementKind_Button: virtuals.xAxis_as_buttons[0] = mReferences[need]; break;
- }
- }
-
- // stick right: right button
- need = mDialogItemToNeedMapping[kDialogItem_StickRight];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: virtuals.xAxis_as_buttons[1] = mReferences[need]; break;
- }
- }
-
- // trim lower: min button and trim axis
- need = mDialogItemToNeedMapping[kDialogItem_TrimLower];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: virtuals.trim = mReferences[need]; break;
- case kISpElementKind_Button: virtuals.trim_as_buttons[0] = mReferences[need]; break;
- }
- }
-
- // trim higher: max button
- need = mDialogItemToNeedMapping[kDialogItem_TrimHigher];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: virtuals.trim_as_buttons[1] = mReferences[need]; break;
- }
- }
-
- // throttle lower: min button and throttle axis
- need = mDialogItemToNeedMapping[kDialogItem_ThrottleLower];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: virtuals.throttle = mReferences[need]; break;
- case kISpElementKind_Button: virtuals.throttle_as_buttons[0] = mReferences[need]; break;
- }
- }
-
- // throttle higher: max button
- need = mDialogItemToNeedMapping[kDialogItem_ThrottleHigher];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: virtuals.throttle_as_buttons[1] = mReferences[need]; break;
- }
- }
-
- // rudder lower: min button and rudder axis
- need = mDialogItemToNeedMapping[kDialogItem_RudderLeft];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: virtuals.rudder = mReferences[need]; break;
- case kISpElementKind_Button: virtuals.rudder_as_buttons[0] = mReferences[need]; break;
- }
- }
-
- // rudder higher: max button
- need = mDialogItemToNeedMapping[kDialogItem_RudderRight];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: virtuals.rudder_as_buttons[1] = mReferences[need]; break;
- }
- }
-
- // brake pedal
- need = mDialogItemToNeedMapping[kDialogItem_BrakeDepressed];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: virtuals.brake = mReferences[need]; break;
- case kISpElementKind_Button: virtuals.brake_as_button = mReferences[need]; break;
- }
- }
-
- // gas pedal
- need = mDialogItemToNeedMapping[kDialogItem_GasDepressed];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: virtuals.gas = mReferences[need]; break;
- case kISpElementKind_Button: virtuals.gas_as_button = mReferences[need]; break;
- }
- }
-
- // dpads
- for (UInt32 dpad_itr = 0; dpad_itr < features.numDPads; dpad_itr++)
- {
- // dpad up: up button, y axis, movement, dpad
- need = mDialogItemToNeedMapping[kDialogItem_DPad1Up + (dpad_itr * 4)];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_DPad: virtuals.dpads[dpad_itr] = mReferences[need]; break;
- case kISpElementKind_Movement: virtuals.dpads_as_movement[dpad_itr] = mReferences[need]; break;
- case kISpElementKind_Axis: virtuals.dpads_as_axis[dpad_itr][1] = mReferences[need]; break;
- case kISpElementKind_Button: virtuals.dpads_as_buttons[dpad_itr][0] = mReferences[need]; break;
- }
- }
-
- // dpad down: down button
- need = mDialogItemToNeedMapping[kDialogItem_DPad1Down + (dpad_itr * 4)];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: virtuals.dpads_as_buttons[dpad_itr][2] = mReferences[need]; break;
- }
- }
-
- // dpad left: left button and x axis
- need = mDialogItemToNeedMapping[kDialogItem_DPad1Left + (dpad_itr * 4)];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: virtuals.dpads_as_axis[dpad_itr][0] = mReferences[need]; break;
- case kISpElementKind_Button: virtuals.dpads_as_buttons[dpad_itr][1] = mReferences[need]; break;
- }
- }
-
- // dpad right: right button
- need = mDialogItemToNeedMapping[kDialogItem_DPad1Right + (dpad_itr * 4)];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: virtuals.dpads_as_buttons[dpad_itr][3] = mReferences[need]; break;
- }
- }
-
- }
-
- // buttons
- for (UInt32 button_itr = 0; button_itr < features.numButtons; button_itr++)
- {
- need = mDialogItemToNeedMapping[kDialogItem_Button1 + button_itr];
-
- if (need != kUnsetIndex)
- virtuals.buttons[button_itr] = mReferences[need];
- }
- }
-
- void ISpUSBDevice::ClearVirtuals (void)
- {
- virtuals.xAxis = nil;
- virtuals.yAxis = nil;
- virtuals.trim = nil;
- virtuals.throttle = nil;
- virtuals.rudder = nil;
- virtuals.brake = nil;
- virtuals.gas = nil;
-
- virtuals.stickMovement = nil;
- virtuals.stickDPad = nil;
-
- virtuals.xAxis_as_buttons[0] = nil;
- virtuals.yAxis_as_buttons[0] = nil;
- virtuals.trim_as_buttons[0] = nil;
- virtuals.throttle_as_buttons[0] = nil;
- virtuals.rudder_as_buttons[0] = nil;
- virtuals.brake_as_button = nil;
- virtuals.gas_as_button = nil;
-
- virtuals.xAxis_as_buttons[1] = nil;
- virtuals.yAxis_as_buttons[1] = nil;
- virtuals.trim_as_buttons[1] = nil;
- virtuals.throttle_as_buttons[1] = nil;
- virtuals.rudder_as_buttons[1] = nil;
-
- // dpads
- UInt32 dpad_itr;
- for(dpad_itr = 0; dpad_itr < kMaxHighLevelDpads; dpad_itr++)
- {
- virtuals.dpads[dpad_itr] = nil;
- virtuals.dpads_as_movement[dpad_itr] = nil;
- virtuals.dpads_as_buttons[dpad_itr][0] = nil;
- virtuals.dpads_as_buttons[dpad_itr][1] = nil;
- virtuals.dpads_as_buttons[dpad_itr][2] = nil;
- virtuals.dpads_as_buttons[dpad_itr][3] = nil;
- virtuals.dpads_as_axis[dpad_itr][0] = nil;
- virtuals.dpads_as_axis[dpad_itr][1] = nil;
- }
-
- // buttons
- UInt32 button_itr;
- for(button_itr = 0; button_itr < kMaxHighLevelButtons; button_itr++)
- {
- virtuals.buttons[button_itr] = nil;
- }
- }
-
-
- OSStatus ISpUSBDevice::Initialize(FSSpec fileSpec)
- {
- OSStatus err = noErr;
- short resource_ref = -1; // ref to our resource file
- Boolean resource_file_open = false; // true if our resource file is open, (we open if we find a device)
- USBDeviceRef usbDeviceRef;
- CFragConnectionID usbModuleConnID;
- UHIDModuleDispatchTablePtr hidModuleDispatchTable;
- CFragSymbolClass symClass;
- ISpUSBDevice * ispUSBDevice = nil;
- ListNode * listNode;
-
- int dummy = 1;
-
- gUSBDevices = List_New();
- if (!gUSBDevices) return memFullErr;
-
- // open the resource file and check for errors
- if (!resource_file_open)
- {
- resource_ref = FSpOpenResFile(&fileSpec, fsRdPerm);
- err = ResError();
-
- // assert and error check
- WARNING(err == noErr, "ISpUSBDevice::Initialize failed to open res file");
- if (err != noErr) { return err; }
-
- resource_file_open = true; // used to know to close res file
- }
-
- usbDeviceRef = 0;
- while (!err)
- {
- err = USBGetNextDeviceByClass (&usbDeviceRef, &usbModuleConnID, kUSBHIDClass, kUSBNoInterfaceSubClass, kUSBNoInterfaceProtocol);
- // if error, then either no more devices, or some real errors
- if (err) break;
-
- err = FindSymbol (usbModuleConnID, "\pTheUHIDModuleDispatchTable", (Ptr *)&hidModuleDispatchTable, &symClass);
- if (err) continue; // this is not a compliant hid device, doesn't export right symbol
-
- // version checking
- if (hidModuleDispatchTable->dispatchTableCurrentVersion < kOldestCompatableDispatchTableVersion)
- continue;
- if (hidModuleDispatchTable->dispatchTableOldestVersion > kCurrentDispatchTableVersion)
- continue;
-
- // in order to make a minimal change, we will claim the device and then immediately release it
- // if we are successful, because we are going to claim it again in Patch() which is called from
- // finish construction below.
- // however, if we cannot claim the device, the a different driver is already loaded which
- // talks to the device, so we don't want to create a connection here
- UHIDModuleConnectionID connectionID;
- err = (*hidModuleDispatchTable->pUHIDClaimDevice)(&connectionID, 0);
- if (err) continue; // somebody else has cliamed the device, so don't try to get it
-
- // we claimed it, so now release it
- err = (*hidModuleDispatchTable->pUHIDReleaseDevice)(connectionID);
- WARNING(err == noErr, "USBDevice::Initialize UHIDReleaseDevice failed");
-
- // allocate the list node to keep track of our list
- listNode = List_NewNode(gUSBDevices, kListDontAdd);
- WARNING(listNode != nil, "ISpUSBDevice failed to allocate list node");
- if (!listNode) return memFullErr;
-
- // for each class, we'll see its supported, and if it is, we'll create it
- if (TMTopGun::IsTMTopGun(hidModuleDispatchTable))
- ispUSBDevice = new TMTopGun(hidModuleDispatchTable, usbDeviceRef, fileSpec);
- else if (GravisPad::IsGravisPad(hidModuleDispatchTable))
- ispUSBDevice = new GravisPad(hidModuleDispatchTable, usbDeviceRef, fileSpec);
-
- // didn't match on any subclass, so we'll give up
- else
- {
- List_DisposeNode(listNode);
- continue;
- }
-
- // we need to not do a lot of work in constructer, because subclass not created yet
- ispUSBDevice->FinishConstruction();
-
- // if we're here, then we called some classes constructer
- WARNING(ispUSBDevice != nil, "ISpUSBDevice failed to allocate");
-
- listNode->data = ispUSBDevice;
- List_AddTail(gUSBDevices, listNode);
- }
-
- if (err == kUSBNotFound)
- err = noErr; // don't return an error if just no _more_ usb devices
-
- // if needed close the resource file
- if (resource_file_open) { CloseResFile(resource_ref); }
-
- return noErr;
- }
-
- /* =============================================================================
- * Terminate (public, static)
- *
- * Gets rid of all our devices.
- * ========================================================================== */
- void ISpUSBDevice::Terminate(
- void)
- {
- void * listData;
-
- List_BeginIteration(gUSBDevices, kListIterateForward, false);
-
- // get rid of all the usb devices we created
- while ((listData = List_Iterate (gUSBDevices)) != nil)
- {
- ISpUSBDevice * device = (ISpUSBDevice *) listData;
- delete device;
- }
-
- List_EndIteration (gUSBDevices);
-
- // we'll initialize list, so it's empty in case things go wacky
- List_Initialize (gUSBDevices);
- }
-
-
- void ISpUSBDevice::ParseData(
- Ptr inBuffer)
- {
- OSStatus err;
-
- if (!mActive) return;
-
- AbsoluteTime time = ISpUptime();
-
- // Parse the data
- UInt32 itr;
- for(itr = 0; itr < mUSBElementCount; itr++)
- {
- // skip non-valid items
- if (!mUSBMapping[itr].valid) continue;
-
- UInt32 * curHLDataPtr;
- curHLDataPtr = nil;
-
- SInt32 elementValue;
- elementValue = ParseElementValue(itr, inBuffer);
-
- Boolean shouldReverse = false;
-
- UInt32 data = 0;
- switch (mUSBMapping[itr].kind)
- {
- case kISpElementKind_Axis:
- double float_data;
-
- float_data = (elementValue - mUSBMapping[itr].min);
- float_data *= mUSBMapping[itr].multiplier;
-
- #if 0
- // rudders backwards?
- if (mUSBMapping[itr].highIndex == kISpElementLabel_Axis_Rudder)
- float_data = kISpAxisMaximum - float_data;
- #endif
-
- // clip it
- if (float_data < kISpAxisMinimum)
- data = kISpAxisMinimum;
- else if (float_data > kISpAxisMaximum)
- data = kISpAxisMaximum;
- else
- data = float_data;
-
- switch(mUSBMapping[itr].highIndex)
- {
- case kISpElementLabel_Axis_XAxis: curHLDataPtr = &mCurHLData.xAxis; break;
-
- case kISpElementLabel_Axis_YAxis: curHLDataPtr = &mCurHLData.yAxis;
- shouldReverse = mReverseStick; break;
-
- case kISpElementLabel_Axis_Trim: curHLDataPtr = &mCurHLData.trim;
- shouldReverse = mReverseTrim; break;
-
- case kISpElementLabel_Axis_Throttle: curHLDataPtr = &mCurHLData.throttle;
- shouldReverse = mReverseThrottle; break;
-
- case kISpElementLabel_Axis_Rudder: curHLDataPtr = &mCurHLData.rudder;
- shouldReverse = mReverseRudder; break;
-
- case kISpElementLabel_Axis_Gas: curHLDataPtr = &mCurHLData.gas; break;
- case kISpElementLabel_Axis_Brake: curHLDataPtr = &mCurHLData.brake; break;
- }
- break;
-
- case kISpElementKind_Button:
- data = elementValue;
- curHLDataPtr = &mCurHLData.buttons[mUSBMapping[itr].highIndex];
- break;
-
- case kISpElementKind_DPad:
- if (mUSBMapping[itr].usbElementKey != kUSB_dpad4_element)
- {
- switch (elementValue)
- {
- default:
- case 0: data = kISpPadIdle; break;
- case 1: data = kISpPadUp; break;
- case 2: data = kISpPadUpRight; break;
- case 3: data = kISpPadRight; break;
- case 4: data = kISpPadDownRight; break;
- case 5: data = kISpPadDown; break;
- case 6: data = kISpPadDownLeft; break;
- case 7: data = kISpPadLeft; break;
- case 8: data = kISpPadUpLeft; break;
- }
- }
- else
- {
- switch (elementValue)
- {
- default:
- case 0: data = kISpPadIdle; break;
- case 1: data = kISpPadUp; break;
- case 2: data = kISpPadRight; break;
- case 3: data = kISpPadDown; break;
- case 4: data = kISpPadLeft; break;
- }
- }
- curHLDataPtr = &mCurHLData.dpads[mUSBMapping[itr].highIndex];
- shouldReverse = mReverseDPad[mUSBMapping[itr].highIndex];
- break;
- }
-
- if (data != mUSBMapping[itr].lastValue)
- {
- mUSBMapping[itr].lastValue = data;
- err = ISpElement_PushSimpleData(mUSBMapping[itr].element, data, &time);
-
- // do we need to pass this to the high level ?
- if (mUSBMapping[itr].highLevelValid && curHLDataPtr)
- {
- if (shouldReverse)
- {
- switch (mUSBMapping[itr].kind)
- {
- case kISpElementKind_Axis:
- data = kISpAxisMaximum - data;
- break;
-
- case kISpElementKind_DPad:
- data = DPadReverseVertical(data);
- break;
- }
- }
-
- *curHLDataPtr = data;
- }
- }
- }
-
- // set the _as_buttons, and _as_axis fields
- SetAsFields(mCurHLData);
-
- // push data into the virtual elements
- PushDataToVirtuals(mCurHLData);
-
- // set the old state
- mOldHLData = mCurHLData;
- }
-
- /*
- *
- * IsPressed
- *
- * This function returns true if this dialog item 'pressed' (ie on the device)
- *
- */
-
- Boolean ISpUSBDevice::IsPressed (short inDialogItem)
- {
- UInt32 array_index = inDialogItem - mBaseDITLCount - kDialogItem_FirstPopup;
-
- WARNING(array_index >= 0, "IsPressed array_index out of range (to small)");
- WARNING(array_index < kDialogItem_NumPopups, "IsPressed array_index out of range (to large)");
-
- return mPopupPressed[array_index];
- }
-
- void ISpUSBDevice::UpdateAllButtons(void)
- {
- HighLevelData theHLData = mOldHLData;
-
- if (features.hasXAxis)
- {
- UpdateSingleButton(theHLData.xAxis_as_buttons[0], kDialogItem_StickLeft);
- UpdateSingleButton(theHLData.xAxis_as_buttons[1], kDialogItem_StickRight);
- }
- if (features.hasYAxis)
- {
- UpdateSingleButton(theHLData.yAxis_as_buttons[0], kDialogItem_StickDown);
- UpdateSingleButton(theHLData.yAxis_as_buttons[1], kDialogItem_StickUp);
- }
- if (features.hasTrim)
- {
- UpdateSingleButton(theHLData.trim_as_buttons[0], kDialogItem_TrimLower);
- UpdateSingleButton(theHLData.trim_as_buttons[1], kDialogItem_TrimHigher);
- }
- if (features.hasThrottle)
- {
- UpdateSingleButton(theHLData.throttle_as_buttons[0], kDialogItem_ThrottleLower);
- UpdateSingleButton(theHLData.throttle_as_buttons[1], kDialogItem_ThrottleHigher);
- }
- if (features.hasRudder)
- {
- UpdateSingleButton(theHLData.rudder_as_buttons[0], kDialogItem_RudderLeft);
- UpdateSingleButton(theHLData.rudder_as_buttons[1], kDialogItem_RudderRight);
- }
- if (features.hasBrake)
- {
- UpdateSingleButton(theHLData.brake_as_button, kDialogItem_BrakeDepressed);
- }
- if (features.hasGas)
- {
- UpdateSingleButton(theHLData.gas_as_button, kDialogItem_GasDepressed);
- }
-
- for(UInt32 button_itr = 0; button_itr < features.numButtons; button_itr++)
- UpdateSingleButton(theHLData.buttons[button_itr], kDialogItem_Button1 + button_itr);
-
- for (UInt32 dpad_itr = 0; dpad_itr < features.numDPads; dpad_itr++)
- {
- UpdateSingleButton(theHLData.dpads_as_buttons[dpad_itr][0], kDialogItem_DPad1Up + (dpad_itr * 4));
- UpdateSingleButton(theHLData.dpads_as_buttons[dpad_itr][2], kDialogItem_DPad1Down + (dpad_itr * 4));
- UpdateSingleButton(theHLData.dpads_as_buttons[dpad_itr][1], kDialogItem_DPad1Left + (dpad_itr * 4));
- UpdateSingleButton(theHLData.dpads_as_buttons[dpad_itr][3], kDialogItem_DPad1Right + (dpad_itr * 4));
- }
- }
-
- void ISpUSBDevice::UpdateSingleButton(UInt32 curButton, UInt32 index)
- {
- WARNING(mDialog != nil, "ISpUSBDevice::UpdateSingleButton mDialog was nil");
- WARNING(mVisable, "ISpUSBDevice::UpdateSingleButton mVisable was false");
-
- WARNING(index > 0, "ISpUSBDevice::UpdateSingleButton index out of range (to small)");
- WARNING(index <= kDialogItem_NumPopups, "ISpUSBDevice::UpdateSingleButton index out of range (to large)");
-
- UInt32 array_index = index - kDialogItem_FirstPopup;
- Boolean changed = false;
-
- if ((!mPopupPressed[array_index]) && (curButton))
- {
- mPopupPressed[array_index] = true;
- changed = true;
- }
- else if ((mPopupPressed[array_index]) && (!curButton))
- {
- mPopupPressed[array_index] = false;
- changed = true;
- }
-
- if (changed)
- { PlotPopupIcon(mBaseDITLCount + index, ttNone); }
- }
-
- ////////////////////////////////////////////////////////
-
-
- ISpElementLabel USBElementKeyToLabel(short usbElementKey)
- {
- ISpElementLabel label;
-
- switch (usbElementKey)
- {
- case kUSB_trigger_element: label = kISpElementLabel_Btn_Fire; break;
-
- case kUSB_button1_element: label = kISpElementLabel_None; break;
- case kUSB_button2_element: label = kISpElementLabel_None; break;
- case kUSB_button3_element: label = kISpElementLabel_None; break;
- case kUSB_button4_element: label = kISpElementLabel_None; break;
- case kUSB_button5_element: label = kISpElementLabel_None; break;
- case kUSB_button6_element: label = kISpElementLabel_None; break;
- case kUSB_button7_element: label = kISpElementLabel_None; break;
- case kUSB_button8_element: label = kISpElementLabel_None; break;
-
- case kUSB_buttonSelect_element: label = kISpElementLabel_Btn_Select; break;
- case kUSB_buttonStart_element: label = kISpElementLabel_Btn_PauseResume; break;
-
- case kUSB_povhat_element: label = kISpElementLabel_Pad_POV; break;
- case kUSB_povhat4_element: label = kISpElementLabel_Pad_POV; break;
- case kUSB_dpad_element: label = kISpElementLabel_Pad_Move; break;
- case kUSB_dpad4_element: label = kISpElementLabel_Pad_Move; break;
-
- case kUSB_xaxis_element: label = kISpElementLabel_Axis_XAxis; break;
- case kUSB_yaxis_element: label = kISpElementLabel_Axis_YAxis; break;
- case kUSB_throttle_element: label = kISpElementLabel_Axis_Throttle; break;
- case kUSB_rudder_element: label = kISpElementLabel_Axis_Rudder; break;
- case kUSB_trim_element: label = kISpElementLabel_Axis_Trim; break;
- case kUSB_gas_element: label = kISpElementLabel_Axis_Gas; break;
- case kUSB_brake_element: label = kISpElementLabel_Axis_Brake; break;
- case kUSB_axis_element: label = kISpElementLabel_None; break;
-
- default: label = kISpElementLabel_None; break;
- }
-
- return label;
- }
-
- OSStatus ISpUSBDevice::BuildMapping(void)
- {
- UInt32 count;
- UInt32 itr;
- ISpElementDefinitionStruct def;
- ISpButtonConfigurationInfo buttonInfo;
- ISpDPadConfigurationInfo dpadInfo;
- ISpAxisConfigurationInfo axisInfo;
- OSStatus err;
- ISpDeviceReference device;
-
- err = CreateDeviceFromResource(GetDeviceResID(), (UInt32) this, device);
- WARNING(err == noErr, "Failed to create the device in BuildMapping");
-
- mDevice = device;
-
- def.device = device;
- def.group = 0;
- def.dataSize = 4;
- def.configInfo = 0;
- def.configInfoLength = 0;
- def.reserved1 = 0;
- def.reserved2 = 0;
- def.reserved3 = 0;
-
- count = GetDeviceElementCount();
- mUSBElementCount = count;
- mUSBMapping = (USBMapping *) NewPtrSysClear( sizeof(USBMapping) * count );
- WARNING(!err && mUSBMapping, "Could not allocate mappings in BuildMapping");
-
- mNumOrderedButtons = 0;
-
- UInt32 buttonCount = 0;
- UInt32 dpadCount = 0;
- UInt32 fireButtonCount = 0;
-
- AbsoluteTime time = ISpUptime ();
-
- for(itr = 0; itr < count; itr++)
- {
- USBMapping *thisMapping = &(mUSBMapping[itr]);
-
- thisMapping->lastValue = 0;
- thisMapping->flags = 0;
-
- UInt32 elementkey;
- thisMapping->usbElementKey = elementkey = GetElementKey(itr);
-
- Str63 elementName;
- GetElementName(itr, elementName);
-
- // def.label and def.theString
- CopyPStr(elementName, def.theString, sizeof (def.theString));
- def.label = USBElementKeyToLabel(elementkey);
-
- switch(elementkey)
- {
- case kUSB_button1_element:
- case kUSB_button2_element:
- case kUSB_button3_element:
- case kUSB_button4_element:
- case kUSB_button5_element:
- case kUSB_button6_element:
- case kUSB_button7_element:
- case kUSB_button8_element:
- case kUSB_trigger_element:
- case kUSB_buttonStart_element:
- case kUSB_buttonSelect_element:
- // fill in element config info
- buttonInfo.id = elementkey;
- if (elementkey == kUSB_trigger_element)
- buttonInfo.id = 1; // you should never have _both_ button1 and trigger
- else if (elementkey == kUSB_buttonStart_element || elementkey == kUSB_buttonSelect_element)
- buttonInfo.id = 0;
-
- // fill in element definition
- def.kind = kISpElementKind_Button;
- def.configInfo = &buttonInfo;
- def.configInfoLength = sizeof (buttonInfo);
-
- // fill in mapping structure
- thisMapping->kind = kISpElementKind_Button;
- thisMapping->valid = true;
-
- // we haven't reached the most high level buttons we can handle
- // make this one do high level stuff as well
- if (buttonCount < kMaxHighLevelButtons)
- {
- thisMapping->highLevelValid = true;
- thisMapping->highIndex = buttonCount;
-
- if (buttonInfo.id != 0)
- {
- mNumOrderedButtons++;
- mOrderedButtonsIndecies[buttonInfo.id - 1] = buttonCount;
- }
-
- buttonCount++;
- }
- break;
-
- case kUSB_povhat_element:
- case kUSB_povhat4_element:
- case kUSB_dpad_element:
- case kUSB_dpad4_element:
- // fill in element config info
- dpadInfo.id = 0; // ignore ordering
- dpadInfo.fourWayPad = (elementkey == kUSB_dpad4_element || elementkey == kUSB_povhat4_element);
-
- // fill in element definition
- def.kind = kISpElementKind_DPad;
- def.configInfo = &dpadInfo;
- def.configInfoLength = sizeof (dpadInfo);
-
- // fill in mapping structure
- thisMapping->kind = kISpElementKind_DPad;
- thisMapping->valid = true;
-
- // if we havent reached the most high level dpads we can
- // handle make this one do high level stuff as well
- if (dpadCount < kMaxHighLevelDpads)
- {
- thisMapping->highLevelValid = true;
- thisMapping->highIndex = dpadCount;
-
- dpadCount++;
- }
- break;
-
- // first we'll do all symmetric axis
- case kUSB_xaxis_element:
- case kUSB_yaxis_element:
- case kUSB_rudder_element:
- case kUSB_trim_element:
- // fill in element config info
- axisInfo.symetricAxis = true;
- thisMapping->flags |= kMappingFlag_AxisIsSymmetric;
-
- // fill in element definition
- def.kind = kISpElementKind_Axis;
- def.configInfo = &axisInfo;
- def.configInfoLength = sizeof (axisInfo);
-
- // fill in mapping structure
- thisMapping->kind = kISpElementKind_Axis;
- thisMapping->valid = true;
- thisMapping->min = GetElementMinValue(itr);
- thisMapping->max = GetElementMaxValue(itr);
- thisMapping->multiplier = kISpAxisMaximum;
- thisMapping->multiplier /= (thisMapping->max - thisMapping->min);
-
- thisMapping->lastValue = kISpAxisMaximum;
-
- thisMapping->highLevelValid = true;
- thisMapping->highIndex = def.label;
- break;
-
- // now we'll do all non-symmetric axis
- case kUSB_throttle_element:
- case kUSB_gas_element:
- case kUSB_brake_element:
- case kUSB_axis_element:
- // fill in element config info
- axisInfo.symetricAxis = false;
-
- // fill in element definition
- def.kind = kISpElementKind_Axis;
- def.configInfo = &axisInfo;
- def.configInfoLength = sizeof (axisInfo);
-
- // fill in mapping structure
- thisMapping->kind = kISpElementKind_Axis;
- thisMapping->valid = true;
- thisMapping->min = GetElementMinValue(itr);
- thisMapping->max = GetElementMaxValue(itr);
- thisMapping->multiplier = kISpAxisMaximum;
- thisMapping->multiplier /= (thisMapping->max - thisMapping->min);
-
- switch(def.label)
- {
- case kISpElementLabel_Axis_XAxis:
- case kISpElementLabel_Axis_YAxis:
- case kISpElementLabel_Axis_Trim:
- case kISpElementLabel_Axis_Throttle:
- case kISpElementLabel_Axis_Rudder:
- case kISpElementLabel_Axis_Brake:
- case kISpElementLabel_Axis_Gas:
- thisMapping->highLevelValid = true;
- thisMapping->highIndex = def.label;
- break;
- }
- break;
- }
-
- if (thisMapping->valid)
- {
- ISpElementReference new_element;
-
- err = ISpElement_New(&def, &new_element);
- WARNING(!err, "pISpElement_New returned an error");
-
- mUSBMapping[itr].element = new_element;
-
- if (err != noErr) { thisMapping->valid = thisMapping->highLevelValid = false; }
- }
- else
- {
- thisMapping->element = nil;
- }
- }
-
- return noErr;
- }
-
- void ISpUSBDevice::DisposeMapping(void)
- {
- UInt32 itr;
- OSStatus err;
-
- for(itr = 0; itr < mUSBElementCount; itr++)
- {
- if (mUSBMapping[itr].valid)
- {
- mUSBMapping[itr].valid = false;
-
- err = ISpElement_Dispose(mUSBMapping[itr].element);
- WARNING(!err, "pISpElementDispose returned an error");
- }
- }
-
- DisposePtr((Ptr) mUSBMapping);
-
- err = ISpDevice_Dispose(mDevice);
- WARNING(!err, "pISpDevice_Dispose returned an error");
- }
-
- void ISpUSBDevice::GetFeatures (void)
- {
- // clear everything
- features.hasXAxis = false;
- features.hasYAxis = false;
- features.hasTrim = false;
- features.hasThrottle = false;
- features.hasRudder = false;
- features.hasBrake = false;
- features.hasGas = false;
-
- features.numDPads = 0;
- features.numButtons = 0;
- features.triggerButtonIndex = kUnsetIndex;
- features.startButtonIndex = kUnsetIndex;
- features.selectButtonIndex = kUnsetIndex;
-
- features.xAxisIndex = 0;
- features.yAxisIndex = 0;
- features.trimIndex = 0;
- features.throttleIndex = 0;
- features.rudderIndex = 0;
- features.brakeIndex = 0;
- features.gasIndex = 0;
-
- {
- for(UInt32 clearItr = 0; clearItr < kMaxHighLevelButtons; clearItr++)
- features.buttonIndex[clearItr] = 0;
- }
-
- {
- for(UInt32 clearItr = 0; clearItr < kMaxHighLevelDpads; clearItr++)
- {
- features.dpadIndex[clearItr] = 0;
- features.is4WayDPad[clearItr] = false;
- }
- }
-
- // get features
- UInt8 buttonCount = 0;
- UInt8 dpadCount = 0;
-
- for(UInt32 itr = 0; itr < mUSBElementCount; itr++)
- {
- USBMapping *thisMapping = &(mUSBMapping[itr]);
-
- if (!thisMapping->valid || !thisMapping->highLevelValid)
- continue;
-
- switch (thisMapping->kind)
- {
- case kISpElementKind_Button:
- {
- ISpElementInfo info;
- OSStatus err = ISpElement_GetInfo(thisMapping->element, &info);
-
- if (info.theLabel == kISpElementLabel_Btn_Fire && features.triggerButtonIndex == kUnsetIndex)
- features.triggerButtonIndex = buttonCount;
- else if (info.theLabel == kISpElementLabel_Btn_PauseResume && features.startButtonIndex == kUnsetIndex)
- features.startButtonIndex = buttonCount;
- else if (info.theLabel == kISpElementLabel_Btn_Select && features.selectButtonIndex == kUnsetIndex)
- features.selectButtonIndex = buttonCount;
-
- if (buttonCount < kMaxHighLevelButtons)
- features.buttonIndex[buttonCount] = itr;
-
- buttonCount++;
- }
- break;
-
- case kISpElementKind_DPad:
- {
- Boolean is4WayDPad = false;
-
- ISpDPadConfigurationInfo dpadInfo;
- OSStatus err = ISpElement_GetConfigurationInfo (thisMapping->element, sizeof (dpadInfo), &dpadInfo);
- if (!err) is4WayDPad = dpadInfo.fourWayPad;
-
- if (dpadCount < kMaxHighLevelDpads)
- {
- features.dpadIndex[dpadCount] = itr;
- features.is4WayDPad[dpadCount] = is4WayDPad;
- }
- dpadCount++;
- }
- break;
-
- case kISpElementKind_Axis:
- {
- ISpElementInfo info;
- OSStatus err = ISpElement_GetInfo(thisMapping->element, &info);
-
- if (!err) switch (info.theLabel)
- {
- case kISpElementLabel_Axis_XAxis:
- if (!features.xAxisIndex)
- features.xAxisIndex = itr;
- features.hasXAxis = true;
- break;
- case kISpElementLabel_Axis_YAxis:
- if (!features.yAxisIndex)
- features.yAxisIndex = itr;
- features.hasYAxis = true;
- break;
- case kISpElementLabel_Axis_Trim:
- if (!features.trimIndex)
- features.trimIndex = itr;
- features.hasTrim = true;
- break;
- case kISpElementLabel_Axis_Throttle:
- if (!features.throttleIndex)
- features.throttleIndex = itr;
- features.hasThrottle = true;
- break;
- case kISpElementLabel_Axis_Rudder:
- if (!features.rudderIndex)
- features.rudderIndex = itr;
- features.hasRudder = true;
- break;
- case kISpElementLabel_Axis_Brake:
- if (!features.brakeIndex)
- features.brakeIndex = itr;
- features.hasBrake = true;
- break;
- case kISpElementLabel_Axis_Gas:
- if (!features.gasIndex)
- features.gasIndex = itr;
- features.hasGas = true;
- break;
- }
- }
- break;
- }
- }
-
- if (buttonCount > kMaxHighLevelButtons )
- buttonCount = kMaxHighLevelButtons;
-
- if (dpadCount > kMaxHighLevelDpads )
- dpadCount = kMaxHighLevelDpads;
-
- features.numDPads = dpadCount;
- features.numButtons = buttonCount;
- }
-
- OSStatus ISpUSBDevice::GetSize(Point &minimum, Point &best)
- {
- Point size;
-
- // this is the size of the generic DITL, which we'll probably never use except in development
- size.h = 394;
- size.v = 316;
-
- best = minimum = size;
-
- return noErr;
- }
-
- UInt16 ISpUSBDevice::GetDeviceResID (void)
- {
- return kResID_Generic;
- }
-
- UInt32 ISpUSBDevice::GetDeviceElementCount (void)
- {
- return 0;
- };
-
- UInt32 ISpUSBDevice::GetElementKey(UInt32 inElementIndex)
- {
- #pragma unused(inElementIndex)
-
- return 0;
- };
-
- void ISpUSBDevice::GetElementName (UInt32 inElementIndex, Str31 outElementName)
- {
- #pragma unused(inElementIndex)
- #pragma unused(outElementName)
- };
-
- SInt32 ISpUSBDevice::GetElementMinValue(UInt32 inElementIndex)
- {
- #pragma unused(inElementIndex)
-
- return 0;
- };
-
- SInt32 ISpUSBDevice::GetElementMaxValue(UInt32 inElementIndex)
- {
- #pragma unused(inElementIndex)
-
- return 0;
- };
-
- SInt32 ISpUSBDevice::ParseElementValue(UInt32 inElementIndex, Ptr inBuffer)
- {
- #pragma unused(inElementIndex)
- #pragma unused(inBuffer)
-
- return 0;
- };
-
-
- // ************************************************************ //
- // * TMTopGun //
- // ************************************************************ //
-
- Boolean TMTopGun::IsTMTopGun(UHIDModuleDispatchTablePtr hidmoduleDispatchTable)
- {
- OSStatus err;
- UInt16 venderID, productID;
-
- err = (*hidmoduleDispatchTable->pUHIDGetDeviceInfo)(kUHIDGetVenderID, &venderID);
- if (err) return false;
-
- err = (*hidmoduleDispatchTable->pUHIDGetDeviceInfo)(kUHIDGetProductID, &productID);
- if (err) return false;
-
- // fail if not our device
- if (venderID != 0x044f || (productID != 0xa0a0 && productID != 0xa0a1)) return false;
-
- return true;
- }
-
- TMTopGun::TMTopGun (
- const UHIDModuleDispatchTablePtr hidmoduleDispatchTable,
- const USBDeviceRef usbDeviceRef,
- const FSSpec &inFileSpec) : ISpUSBDevice (hidmoduleDispatchTable, usbDeviceRef, inFileSpec)
- {
- // everything for now is done in our parent's constructer
- }
-
- TMTopGun::~TMTopGun()
- {
- // everything for now is done in our parent's destructer
- }
-
- OSStatus TMTopGun::GetSize(Point &minimum, Point &best)
- {
- Point size;
-
- size.h = 266;
- size.v = 200;
-
- best = minimum = size;
-
- return noErr;
- }
-
- UInt16 TMTopGun::GetDeviceResID (void)
- {
- return kResID_TMTopGun;
- }
-
- UInt32 TMTopGun::GetDeviceElementCount(void)
- {
- return kTMTopGun_NumElements;
- }
-
- UInt32 TMTopGun::GetElementKey(UInt32 inElementIndex)
- {
- switch (inElementIndex)
- {
- case kTMTopGun_Hat: return kUSB_povhat_element;
-
- case kTMTopGun_Trigger: return kUSB_trigger_element;
- case kTMTopGun_ThumbHigh: return kUSB_button2_element;
- case kTMTopGun_ThumbLow: return kUSB_button3_element;
- case kTMTopGun_Pinky: return kUSB_button4_element;
-
- case kTMTopGun_XAxis: return kUSB_xaxis_element;
- case kTMTopGun_YAxis: return kUSB_yaxis_element;
- }
-
- return 0;
- }
-
- void TMTopGun::GetElementName (UInt32 inElementIndex, Str31 outElementName)
- {
- UInt32 stringIndex;
-
- switch (inElementIndex)
- {
- case kTMTopGun_Hat: stringIndex = kStrList_DefaultNames_POVHat; break;
-
- case kTMTopGun_Trigger: stringIndex = kStrList_DefaultNames_Trigger; break;
- case kTMTopGun_ThumbHigh: stringIndex = kStrList_DefaultNames_Button2; break;
- case kTMTopGun_ThumbLow: stringIndex = kStrList_DefaultNames_Button3; break;
- case kTMTopGun_Pinky: stringIndex = kStrList_DefaultNames_Button4; break;
-
- case kTMTopGun_XAxis: stringIndex = kStrList_DefaultNames_XAxis; break;
- case kTMTopGun_YAxis: stringIndex = kStrList_DefaultNames_YAxis; break;
-
- default: stringIndex = kStrList_DefaultNames_Error; break;
- }
-
- OSStatus err;
- Resource_GetIndString(kStrListResource_DefaultNames, stringIndex, sizeof(Str31), outElementName, &err);
- if (err != noErr) { outElementName[0] = 0; }
- }
-
- SInt32 TMTopGun::GetElementMinValue(UInt32 inElementIndex)
- {
- switch (inElementIndex)
- {
- case kTMTopGun_Hat: return 0;
-
- case kTMTopGun_Trigger: return 0;
- case kTMTopGun_ThumbHigh: return 0;
- case kTMTopGun_ThumbLow: return 0;
- case kTMTopGun_Pinky: return 0;
-
- case kTMTopGun_XAxis: return -128;
- case kTMTopGun_YAxis: return -127; // note we flip this so -127 to 128
- }
-
- return 0;
- }
-
- SInt32 TMTopGun::GetElementMaxValue(UInt32 inElementIndex)
- {
- switch (inElementIndex)
- {
- case kTMTopGun_Hat: return 1;
-
- case kTMTopGun_Trigger: return 1;
- case kTMTopGun_ThumbHigh: return 1;
- case kTMTopGun_ThumbLow: return 1;
- case kTMTopGun_Pinky: return 1;
-
- case kTMTopGun_XAxis: return 127;
- case kTMTopGun_YAxis: return 128; // note we flip this so -127 to 128
- }
-
- return 0;
- }
-
- SInt32 TMTopGun::ParseElementValue(UInt32 inElementIndex, Ptr inBuffer)
- {
- UInt8 * buffer = (UInt8 *) inBuffer;
-
- // 0 1 2 3
- // packet is: xxxxxxxx yyyyyyyy bbbbhhhh cccccccc
- // where b = button, x = x axis, y = y axis, h = hat
- // button order same as constants
-
- switch (inElementIndex)
- {
- case kTMTopGun_XAxis: return ((SInt8) buffer[0]);
-
- case kTMTopGun_YAxis: return (-(SInt32)((SInt8) buffer[1])); // reverse (flip) this
-
- case kTMTopGun_Hat: return (buffer[2] & 0x0F); // low 4 bits
-
- case kTMTopGun_Trigger: return !!(buffer[2] & 0x10);
- case kTMTopGun_ThumbHigh: return !!(buffer[2] & 0x20);
- case kTMTopGun_ThumbLow: return !!(buffer[2] & 0x40);
- case kTMTopGun_Pinky: return !!(buffer[2] & 0x80);
- }
-
- return 0;
- }
-
- // ************************************************************ //
- // * GravisPad //
- // ************************************************************ //
-
- Boolean GravisPad::IsGravisPad(UHIDModuleDispatchTablePtr hidmoduleDispatchTable)
- {
- OSStatus err;
- UInt16 venderID, productID;
-
- err = (*hidmoduleDispatchTable->pUHIDGetDeviceInfo)(kUHIDGetVenderID, &venderID);
- if (err) return false;
-
- err = (*hidmoduleDispatchTable->pUHIDGetDeviceInfo)(kUHIDGetProductID, &productID);
- if (err) return false;
-
- // fail if not our device
- if (venderID != 0x0428 || productID != 0x55aa) return false;
-
- return true;
- }
-
- GravisPad::GravisPad (
- const UHIDModuleDispatchTablePtr hidmoduleDispatchTable,
- const USBDeviceRef usbDeviceRef,
- const FSSpec &inFileSpec) : ISpUSBDevice (hidmoduleDispatchTable, usbDeviceRef, inFileSpec)
- {
- // everything for now is done in our parent's constructer
- }
-
- GravisPad::~GravisPad()
- {
- // everything for now is done in our parent's destructer
- }
-
- OSStatus GravisPad::GetSize(Point &minimum, Point &best)
- {
- Point size;
-
- size.h = 346;
- size.v = 154;
-
- best = minimum = size;
-
- return noErr;
- }
-
- UInt16 GravisPad::GetDeviceResID (void)
- {
- return kResID_GravisGamepad;
- }
-
- UInt32 GravisPad::GetDeviceElementCount(void)
- {
- return kGravisPad_NumElements;
- }
-
- UInt32 GravisPad::GetElementKey(UInt32 inElementIndex)
- {
- switch (inElementIndex)
- {
- case kGravisPad_DPad: return kUSB_dpad_element;
-
- case kGravisPad_Yellow: return kUSB_button1_element;
- case kGravisPad_Red: return kUSB_button3_element;
- case kGravisPad_Green: return kUSB_button2_element;
- case kGravisPad_Blue: return kUSB_button4_element;
-
- case kGravisPad_LeftTop: return kUSB_button5_element;
- case kGravisPad_LeftBottom: return kUSB_button7_element;
- case kGravisPad_RightTop: return kUSB_button6_element;
- case kGravisPad_RightBottom: return kUSB_button8_element;
-
- case kGravisPad_Select: return kUSB_buttonSelect_element;
- case kGravisPad_Start: return kUSB_buttonStart_element;
- }
-
- return 0;
- }
-
- void GravisPad::GetElementName (UInt32 inElementIndex, Str31 outElementName)
- {
- UInt32 stringIndex;
-
- switch (inElementIndex)
- {
- case kGravisPad_DPad: stringIndex = kStrList_DefaultNames_DPad; break;
-
- case kGravisPad_Yellow: stringIndex = kStrList_DefaultNames_YellowButton; break;
- case kGravisPad_Red: stringIndex = kStrList_DefaultNames_RedButton; break;
- case kGravisPad_Green: stringIndex = kStrList_DefaultNames_GreenButton; break;
- case kGravisPad_Blue: stringIndex = kStrList_DefaultNames_BlueButton; break;
-
- case kGravisPad_LeftTop: stringIndex = kStrList_DefaultNames_LeftIndexTop; break;
- case kGravisPad_LeftBottom: stringIndex = kStrList_DefaultNames_LeftIndexBottom; break;
- case kGravisPad_RightTop: stringIndex = kStrList_DefaultNames_RightIndexTop; break;
- case kGravisPad_RightBottom: stringIndex = kStrList_DefaultNames_RightIndexBottom; break;
-
- case kGravisPad_Select: stringIndex = kStrList_DefaultNames_SelectButton; break;
- case kGravisPad_Start: stringIndex = kStrList_DefaultNames_StartButton; break;
-
- default: stringIndex = kStrList_DefaultNames_Error; break;
- }
-
- OSStatus err;
- Resource_GetIndString(kStrListResource_DefaultNames, stringIndex, sizeof(Str31), outElementName, &err);
- if (err != noErr) { outElementName[0] = 0; }
- }
-
- SInt32 GravisPad::GetElementMinValue(UInt32 inElementIndex)
- {
- switch (inElementIndex)
- {
- case kGravisPad_DPad: return 0;
-
- case kGravisPad_Yellow: return 0;
- case kGravisPad_Red: return 0;
- case kGravisPad_Green: return 0;
- case kGravisPad_Blue: return 0;
-
- case kGravisPad_LeftTop: return 0;
- case kGravisPad_LeftBottom: return 0;
- case kGravisPad_RightTop: return 0;
- case kGravisPad_RightBottom: return 0;
-
- case kGravisPad_Select: return 0;
- case kGravisPad_Start: return 0;
- }
-
- return 0;
- }
-
- SInt32 GravisPad::GetElementMaxValue(UInt32 inElementIndex)
- {
- switch (inElementIndex)
- {
- case kGravisPad_DPad: return 8;
-
- case kGravisPad_Yellow: return 1;
- case kGravisPad_Red: return 1;
- case kGravisPad_Green: return 1;
- case kGravisPad_Blue: return 1;
-
- case kGravisPad_LeftTop: return 1;
- case kGravisPad_LeftBottom: return 1;
- case kGravisPad_RightTop: return 1;
- case kGravisPad_RightBottom: return 1;
-
- case kGravisPad_Select: return 1;
- case kGravisPad_Start: return 1;
- }
-
- return 0;
- }
-
- SInt32 GravisPad::ParseElementValue(UInt32 inElementIndex, Ptr inBuffer)
- {
- UInt8 * buffer = (UInt8 *) inBuffer;
- UInt32 xaxis, yaxis;
-
- // 0 1 2 3
- // packet is: xxxxxxxx yyyyyyyy bbbbbbbb ccccccbb
- // where b = button, x = x axis, y = y axis
- // button order same as constants
-
- switch (inElementIndex)
- {
- case kGravisPad_DPad:
- // we know it's really a dpad, so we're gonna convert it to usb like dpad values
- xaxis = buffer[0];
- yaxis = buffer[1];
-
- if (yaxis > 0xbf) // is down + ...
- {
- if (xaxis < 0x3f) return 6; // is left
- else if (xaxis > 0xbf) return 4; // is right
- else return 5; // is middle
-
- }
- else if (yaxis < 0x3f) // is up + ...
- {
- if (xaxis < 0x3f) return 8; // is left
- else if (xaxis > 0xbf) return 2; // is right
- else return 1; // is middle
- }
- else // is middle + ...
- {
- if (xaxis < 0x3f) return 7; // is left
- else if (xaxis > 0xbf) return 3; // is right
- else return 0; // is middle
- }
-
- case kGravisPad_Yellow: return !!(buffer[2] & 0x02);
- case kGravisPad_Red: return !!(buffer[2] & 0x01);
- case kGravisPad_Green: return !!(buffer[2] & 0x04);
- case kGravisPad_Blue: return !!(buffer[2] & 0x08);
-
- case kGravisPad_LeftBottom: return !!(buffer[2] & 0x10);
- case kGravisPad_RightBottom: return !!(buffer[2] & 0x20);
- case kGravisPad_LeftTop: return !!(buffer[2] & 0x40);
- case kGravisPad_RightTop: return !!(buffer[2] & 0x80);
-
- case kGravisPad_Select: return !!(buffer[3] & 0x01);
- case kGravisPad_Start: return !!(buffer[3] & 0x02);
- }
-
- return 0;
- }
-
-
-